Преглед изворни кода

更新MCU工程:
修复CPU起来后MCU程序不能访问SYSCTRL寄存器所导致的获取系统时间错误的问题。
更新CPU工程:
修复CPU未使用的模块也会进行时钟初始化导致MCU设置的RTC时钟被修改的问题。

helen пре 2 месеци
родитељ
комит
5aaef1d6cf

+ 31 - 0
AMT630HV160 SDK代码使用注意事项.pdf

@@ -0,0 +1,31 @@
+CONFIDENTIALAMT630HV160 SDK
+     代码使用注意事项
+
+版本:   V1.0
+日期:  2025-09
+
+     1/3
+      深圳开阳电子股份有限公司拥有随时修改本手册的权利,内容如有更改,恕
+不另行通知。深圳开阳电子股份有限公司对本手册不承担任何形式的保证,包括
+但不限于对产品特定用途适销性和适用性的隐含保证。深圳开阳电子股份有限公
+司对本手册中包含的错误或对本手册的使用所带来的偶然或继起损害不承担任何
+责任。
+CONFIDENTIAL
+版本记录:          版本号        更新说明
+
+         日期    V1.0 初始版本
+      2025-09
+
+                    2/3
+CONFIDENTIAL1 MCU 访问系统 SYSCTL 寄存器限制说明
+                 CPU 工程启动前,MCU 具有访问系统 SYSCTL 寄存器的权限;CPU 工程启动后,
+
+            CPU 获取系统 SYSCTL 寄存器的访问权限,此时 MCU 失去对系统 SYSCTL 寄存器的访
+            问权限,MCU 读写系统 SYSCTL 寄存器无效(可以正常读写寄存器,但是读取的数
+            据值异常,写寄存器无效),所以在 CPU 工程启动后,MCU 不能继续访问系统 SYSCTL
+            寄存器,否则会引发未知的异常。因此,MCU 工程中对系统 SYSCTL 寄存器的读写
+            操作必须在 CPU 工程启动前进行,如果需要实时使用系统 SYSCTL 寄存器的值,需
+            要在 CPU 工程启动前进行读取并保存(到变量中)使用。
+
+                                                                                 3/3
+

+ 9 - 0
amt630hv160-freertos-beta/ArkmicroFiles/libboard-amt630hv160/include/board.h

@@ -236,6 +236,15 @@
 #define EC_SPI1_SUPPORT
 /*******************************************/
 
+/************ adc configuration ************/
+//#define ADC_SUPPORT
+#ifdef ADC_SUPPORT
+//#define ADC0_SUPPORT
+//#define ADC1_SUPPORT
+//#define ADC2_SUPPORT
+#endif
+/*******************************************/
+
 
 /************ dma configuration ************/
 /* the smaller channel has higher priority */

+ 13 - 0
amt630hv160-freertos-beta/ArkmicroFiles/libcpu-amt630hv160/source/adc.c

@@ -402,6 +402,19 @@ int adc_init(void)
 	int id;
 
 	for (id = 0; id < ADC_ID_MAX; id++) {
+#ifndef ADC0_SUPPORT
+		if (id == ADC0)
+			continue;
+#endif
+#ifndef ADC1_SUPPORT
+		if (id == ADC1)
+			continue;
+#endif
+#ifndef ADC2_SUPPORT
+		if (id == ADC2)
+			continue;
+#endif
+
 		adc = &g_adc[id];
 
 		vClkSetRate(adc->clk_id, ADC_CLK_FREQ);

+ 15 - 4
amt630hv160-freertos-beta/ArkmicroFiles/libcpu-amt630hv160/source/clock.c

@@ -220,6 +220,7 @@ xClockProperty xClocks[] = {
 	.u.sys_property.div_value = 4,},
 #endif
 #endif
+#ifdef EC_SPI1_SUPPORT
 	{.clkid = CLK_SPI1, .clktype = SYS_CLOCK, .clksource = {CLK_XTAL24M, CLK_CPUPLL},
 	 .enable_reg = {REGS_SYSCTL_BASE + SYS_BUS_CLK_EN1, REGS_SYSCTL_BASE + SYS_PER_CLK_EN},
 	 .enable_offset = {2, 1}, .enable_bits = 2,
@@ -227,6 +228,8 @@ xClockProperty xClocks[] = {
 	 .u.sys_property.index_mask = 0x1, .u.sys_property.index_value = 0,
 	 .u.sys_property.div_offset = 16, .u.sys_property.div_mask = 0xf,
 	 .u.sys_property.div_value = 1, .u.sys_property.div_mode = DIVMODE_PLUSONE,},
+#endif
+#ifdef DW_SPI2_SUPPORT
 	{.clkid = CLK_SPI2, .clktype = SYS_CLOCK, .clksource = {CLK_XTAL24M, CLK_CPUPLL},
 	 .enable_reg = {REGS_SYSCTL_BASE + SYS_BUS_CLK_EN, REGS_SYSCTL_BASE + SYS_PER_CLK_EN},
 	 .enable_offset = {27, 29}, .enable_bits = 2,
@@ -234,31 +237,39 @@ xClockProperty xClocks[] = {
 	 .u.sys_property.index_mask = 0x1, .u.sys_property.index_value = 0,
 	 .u.sys_property.div_offset = 24, .u.sys_property.div_mask = 0xf,
 	 .u.sys_property.div_value = 1, .u.sys_property.div_mode = DIVMODE_PLUSONE,},
+#endif
+	//PWM时钟配置和MCU_PWM是复用的,默认是24Mhz,如果要修改的话需要在MCU工程修改
 	{.clkid = CLK_PWM, .clktype = SYS_CLOCK, .clksource = {CLK_XTAL24M, CLK_SYSPLL},
 	 .enable_reg = {REGS_SYSCTL_BASE + SYS_BUS_CLK_EN1, REGS_SYSCTL_BASE + SYS_PER_CLK_EN},
 	 .enable_offset = {15, 10}, .enable_bits = 2,
 	 .u.sys_property.cfgreg = REGS_SYSCTL_BASE + SYS_PER_CLK_CFG, .u.sys_property.index_offset = 8,
-	 .u.sys_property.index_mask = 0x1, .u.sys_property.index_value = 0,
+	 .u.sys_property.index_mask = 0x1, .u.sys_property.index_value = -1,
 	 .u.sys_property.div_offset = 4, .u.sys_property.div_mask = 0xf,
 	 .u.sys_property.div_value = 1, .u.sys_property.div_mode = DIVMODE_PLUSONE,},
+#ifdef ADC0_SUPPORT
 	{.clkid = CLK_ADC, .clktype = SYS_CLOCK, .clksource = {CLK_XTAL24M},
 	 .enable_reg = {REGS_SYSCTL_BASE + SYS_BUS_CLK_EN1, REGS_SYSCTL_BASE + SYS_PER_CLK_EN},
 	 .enable_offset = {5, 13}, .enable_bits = 2,
 	 .u.sys_property.cfgreg = REGS_SYSCTL_BASE + SYS_TIMER_CLK_CFG, .u.sys_property.div_offset = 16,
-	 .u.sys_property.div_mask = 0x7fff, .u.sys_property.div_value = 642,
+	 .u.sys_property.div_mask = 0x7fff, .u.sys_property.div_value = 2400,
 	 .u.sys_property.div_mode = DIVMODE_PONEDOUBLE,},
+#endif
+#ifdef ADC1_SUPPORT
 	{.clkid = CLK_ADC1, .clktype = SYS_CLOCK, .clksource = {CLK_XTAL24M},
 	 .enable_reg = {REGS_SYSCTL_BASE + SYS_BUS_CLK_EN1, REGS_SYSCTL_BASE + SYS_PER_CLK_EN1},
 	 .enable_offset = {25, 14}, .enable_bits = 2,
 	 .u.sys_property.cfgreg = REGS_SYSCTL_BASE + SYS_ADC_CLK1_CFG, .u.sys_property.div_offset = 0,
-	 .u.sys_property.div_mask = 0x7fff, .u.sys_property.div_value = 642,
+	 .u.sys_property.div_mask = 0x7fff, .u.sys_property.div_value = 2400,
 	 .u.sys_property.div_mode = DIVMODE_PONEDOUBLE,},
+#endif
+#ifdef ADC2_SUPPORT
 	{.clkid = CLK_ADC2, .clktype = SYS_CLOCK, .clksource = {CLK_XTAL24M},
 	 .enable_reg = {REGS_SYSCTL_BASE + SYS_BUS_CLK_EN1, REGS_SYSCTL_BASE + SYS_PER_CLK_EN1},
 	 .enable_offset = {26, 15}, .enable_bits = 2,
 	 .u.sys_property.cfgreg = REGS_SYSCTL_BASE + SYS_ADC_CLK1_CFG, .u.sys_property.div_offset = 16,
-	 .u.sys_property.div_mask = 0x7fff, .u.sys_property.div_value = 642,
+	 .u.sys_property.div_mask = 0x7fff, .u.sys_property.div_value = 2400,
 	 .u.sys_property.div_mode = DIVMODE_PONEDOUBLE,},
+#endif
 	{.clkid = CLK_I2S, .clktype = SYS_CLOCK, .clksource = {CLK_SYSPLL, CLK_AHBPLL},
 	 .enable_reg = {REGS_SYSCTL_BASE + SYS_BUS_CLK_EN1, REGS_SYSCTL_BASE + SYS_PER_CLK_EN,
 	  REGS_SYSCTL_BASE + SYS_PER_CLK_EN},

+ 13 - 4
amt630hv160-freertos-beta/ArkmicroFiles/libcpu-amt630hv160/source/sema.c

@@ -176,8 +176,12 @@ void sema_init(void)
 #ifdef DW_SPI0_SUPPORT
 	sema_take(SEMA_GATE_SPI0, portMAX_DELAY);
 #endif
+#ifdef DW_SPI2_SUPPORT
 	sema_take(SEMA_GATE_SPI2, portMAX_DELAY);
+#endif
+#ifdef EC_SPI1_SUPPORT
 	sema_take(SEMA_GATE_ECSPI, portMAX_DELAY);
+#endif
 	sema_take(SEMA_GATE_GPIO, portMAX_DELAY);
 	sema_take(SEMA_GATE_WDT, portMAX_DELAY);
 	sema_take(SEMA_GATE_LCD, portMAX_DELAY);
@@ -219,8 +223,13 @@ void sema_init(void)
 	//sema_take(SEMA_GATE_SDMMC0, portMAX_DELAY);
 
 	// mcu use module
-//	sema_take(SEMA_GATE_ADC0, portMAX_DELAY);
-//	sema_take(SEMA_GATE_ADC1, portMAX_DELAY);
-//	sema_take(SEMA_GATE_ADC2, portMAX_DELAY);
-
+#ifdef ADC0_SUPPORT
+	sema_take(SEMA_GATE_ADC0, portMAX_DELAY);
+#endif
+#ifdef ADC1_SUPPORT
+	sema_take(SEMA_GATE_ADC1, portMAX_DELAY);
+#endif
+#ifdef ADC2_SUPPORT
+	sema_take(SEMA_GATE_ADC2, portMAX_DELAY);
+#endif
 }

+ 6 - 1
amt630hv160-mcu/amt630hv160-mcu-iram/src/ArkmicroFiles/libcpu-amt630hv160/source/amt630hv160_adc.c

@@ -63,6 +63,7 @@ static u32 adc_get_clk(ADC_TypeDef *adc)
 	return clk;
 }
 
+#if 0
 static void adc_set_clk(ADC_TypeDef *adc, u32 freq)
 {
 #ifdef _ADC0
@@ -86,6 +87,7 @@ static void adc_set_clk(ADC_TypeDef *adc, u32 freq)
 		printf("%s set adc clk fail!\n", __func__);
 	}
 }
+#endif
 
 static adc_pdata_t *adc_get_prv_data(ADC_TypeDef *adc)
 {
@@ -271,6 +273,7 @@ void ADC2_IRQHandler(void)
 ///*
 // * high = 1时阈值约等于 1.6v(ADC电源为1.8v时);
 // * high = 0时阈值约定于 0.2v(ADC电源为1.8v时);
+// * 该函数如果要使用的话需放到adc_hardware_init内调用
 // */
 //int adc_int_threshold_sel(ADC_TypeDef *adc, int high)
 //{
@@ -435,14 +438,17 @@ void adc_hardware_init(void)
 		由于原厂开发板中每个ADC的8个管脚并联,导致必须将8个管脚都设为输入才能正常触发ADC
 	*/
 #ifdef _ADC0
+	ADC0_SetClk(ADC_CLK_FREQ);
 	writel(readl(0x50900184) | (0xff << 15), 0x50900184);
 #endif /*_ADC0 */
 
 #ifdef _ADC1
+	ADC1_SetClk(ADC_CLK_FREQ);
 	writel(readl(0x50900184) | (0xff << 23), 0x50900184);
 #endif /*_ADC1 */
 
 #ifdef _ADC2
+	ADC2_SetClk(ADC_CLK_FREQ);
 	GPIO_DirectionInput(ADC_CH_AUX0 + 111);
 	GPIO_DirectionInput(ADC_CH_AUX1 + 111);
 	GPIO_DirectionInput(ADC_CH_AUX2 + 111);
@@ -464,7 +470,6 @@ int adc_init(ADC_TypeDef *adc)
 		return -1;
 	}
 
-	adc_set_clk(adc, ADC_CLK_FREQ);
 	adc_reset(adc);
 
 	adc_prv = adc_get_prv_data(adc);

+ 76 - 7
amt630hv160-mcu/amt630hv160-mcu-iram/src/ArkmicroFiles/libcpu-amt630hv160/source/amt630hv160_clk.c

@@ -35,7 +35,18 @@
 #define AHBPLL_SPRD_FREQ		20000	//20k~100k
 #define VPUPLL_SPRD_FREQ		20000	//20k~100k
 
+static u32 ahb_clk_freq;
+static u32 apb_clk_freq;
+static u32 adc0_clk_freq;
+static u32 adc1_clk_freq;
+static u32 adc2_clk_freq;
+static u32 pwm_clk_freq;
 
+/*
+ * 由于暂未对SYSCTRL模块实现互斥访问逻辑,CPU起来后MCU端访问不了SYSCTRL,
+ * 因此该函数只能在StartCpu函数调用前使用,其他涉及SYSCTRL寄存器访问的函数也一样。
+ * CLK_GetAHBFreq,CLK_GetAPBFreq,ADCX_GetClk,PWM_GetClk这些特殊处理过的函数除外
+ */
 u32 CLK_GetPLLFreq(u32 pllcfg)
 {
 	u32 val;
@@ -55,23 +66,33 @@ u32 CLK_GetAHBFreq(void)
 {
 	u32 clksrc;
 
+	if (ahb_clk_freq)
+		return ahb_clk_freq;
+
 	clksrc = (SYSCTRL->BUS_CLK_CFG >> 3) & 1;
 	if (clksrc)
-		return CLK_GetPLLFreq(SYSCTRL->AHBPLL_CFG);
+		ahb_clk_freq = CLK_GetPLLFreq(SYSCTRL->AHBPLL_CFG);
 	else
-		return HSE_Value;
+		ahb_clk_freq = HSE_Value;
+
+	return ahb_clk_freq;
 }
 
 u32 CLK_GetAPBFreq(void)
 {
 	u32 div;
 
+	if (apb_clk_freq)
+		return apb_clk_freq;
+
 	div = (SYSCTRL->BUS_CLK_CFG >> 4) & 3;
 	if (div > 2)
 		div = 2;
 	div = 1 << div;
 
-	return CLK_GetAHBFreq() / div;
+	apb_clk_freq = CLK_GetAHBFreq() / div;
+
+	return apb_clk_freq;
 }
 
 /*
@@ -282,6 +303,11 @@ void SYSCLK_Init(void)
 	SYSCTRL->BUS_CLK_CFG |= (1 << 2) | (1 << 1 ) | (1 << 0);
 
 	TIMER_Udelay(10);
+
+	//此处代码用于CPU起来前访问SYSCTRL获取时钟,不能注释
+	ahb_clk_freq = CLK_GetAHBFreq();
+	apb_clk_freq = CLK_GetAPBFreq();
+	pwm_clk_freq = PWM_GetClk();
 }
 
 void SPI0_SetBusClk(u32 freq)
@@ -642,6 +668,9 @@ void ADC0_SetClk(u32 freq)
 	u32 source_freq;
 	u32 div;
 
+	if (cpu_running)
+		return;
+
 	source_freq = HSE_Value;
 	div = DIV_ROUND_UP(source_freq , freq);
 
@@ -651,6 +680,8 @@ void ADC0_SetClk(u32 freq)
 
 	SYSCTRL->TIMER_CLK_CFG &= ~(0x7fff << 16);
 	SYSCTRL->TIMER_CLK_CFG |= (div << 16);
+
+	adc0_clk_freq = source_freq / ((div + 1) * 2);
 }
 
 u32 ADC0_GetClk(void)
@@ -658,10 +689,15 @@ u32 ADC0_GetClk(void)
 	u32 source_freq;
 	u32 div;
 
+	if (adc0_clk_freq)
+		return adc0_clk_freq;
+
 	source_freq = HSE_Value;
 	div = (((SYSCTRL->TIMER_CLK_CFG >> 16) & 0x7fff) + 1) * 2;
 
-	return source_freq / div;
+	adc0_clk_freq = source_freq / div;
+
+	return adc0_clk_freq;
 }
 
 void ADC1_SetClk(u32 freq)
@@ -669,6 +705,9 @@ void ADC1_SetClk(u32 freq)
 	u32 source_freq;
 	u32 div;
 
+	if (cpu_running)
+		return;
+
 	source_freq = HSE_Value;
 	div = DIV_ROUND_UP(source_freq , freq);
 
@@ -678,6 +717,8 @@ void ADC1_SetClk(u32 freq)
 
 	SYSCTRL->ADC_CLK1_CFG &= ~(0x7fff << 0);
 	SYSCTRL->ADC_CLK1_CFG |= (div << 0);
+
+	adc1_clk_freq = source_freq / ((div + 1) * 2);
 }
 
 u32 ADC1_GetClk(void)
@@ -685,10 +726,15 @@ u32 ADC1_GetClk(void)
 	u32 source_freq;
 	u32 div;
 
+	if (adc1_clk_freq)
+		return adc1_clk_freq;
+
 	source_freq = HSE_Value;
 	div = (((SYSCTRL->ADC_CLK1_CFG >> 0) & 0x7fff) + 1) * 2;
 
-	return source_freq / div;
+	adc1_clk_freq = source_freq / div;
+
+	return adc1_clk_freq;
 }
 
 void ADC2_SetClk(u32 freq)
@@ -696,6 +742,9 @@ void ADC2_SetClk(u32 freq)
 	u32 source_freq;
 	u32 div;
 
+	if (cpu_running)
+		return;
+
 	source_freq = HSE_Value;
 	div = DIV_ROUND_UP(source_freq , freq);
 
@@ -705,6 +754,8 @@ void ADC2_SetClk(u32 freq)
 
 	SYSCTRL->ADC_CLK1_CFG &= ~(0x7fff << 16);
 	SYSCTRL->ADC_CLK1_CFG |= (div << 16);
+
+	adc2_clk_freq = source_freq / ((div + 1) * 2);
 }
 
 u32 ADC2_GetClk(void)
@@ -712,10 +763,15 @@ u32 ADC2_GetClk(void)
 	u32 source_freq;
 	u32 div;
 
+	if (adc2_clk_freq)
+		return adc2_clk_freq;
+
 	source_freq = HSE_Value;
 	div = (((SYSCTRL->ADC_CLK1_CFG >> 16) & 0x7fff) + 1) * 2;
 
-	return source_freq / div;
+	adc2_clk_freq = source_freq / div;
+
+	return adc2_clk_freq;
 }
 
 void PWM_SetClk(u32 freq)
@@ -725,6 +781,9 @@ void PWM_SetClk(u32 freq)
 	u32 val;
 	u32 clk_sel = 0;
 
+	if (cpu_running)
+		return;
+
 	val = SYSCTRL->SYSPLL_CFG;
 	//syspll work
 	if (SYSCTRL->DDR_CTL1_CFG & DDR_CTL1_SYSPLL_EN) {
@@ -748,6 +807,11 @@ void PWM_SetClk(u32 freq)
 	val &= ~(0x1f << 4);
 	val |= ((clk_sel << 4) | (div - 1)) << 4;
 	SYSCTRL->PER_CLK_CFG = val;
+
+	if (clk_sel)
+		pwm_clk_freq = src_freq / div;
+	else
+		pwm_clk_freq = HSE_Value / div;
 }
 
 u32 PWM_GetClk(void)
@@ -755,6 +819,9 @@ u32 PWM_GetClk(void)
 	u32 source_freq;
 	u32 div;
 
+	if (pwm_clk_freq)
+		return pwm_clk_freq;
+
 	if (SYSCTRL->PER_CLK_CFG & (1 << 8))
 		source_freq = CLK_GetPLLFreq(SYSCTRL->SYSPLL_CFG);
 	else
@@ -762,5 +829,7 @@ u32 PWM_GetClk(void)
 
 	div = ((SYSCTRL->PER_CLK_CFG >> 4) & 0xf) + 1;
 
-	return source_freq / div;
+	pwm_clk_freq = source_freq / div;
+
+	return pwm_clk_freq;
 }

+ 0 - 773
amt630hv160-mcu/amt630hv160-mcu-iram/src/ArkmicroFiles/libcpu-amt630hv160/source/amt630hv160_clk_old.c

@@ -1,773 +0,0 @@
-/*******************************************************************************
-* File Name          : amt630hv160_clk.c
-* Author             : Sim
-* Date First Issued  : 05/04/2023
-* Description        : This file provides all the Clock Config functions.
-********************************************************************************
-* History:
-* 05/04/2023: V0.1
-*******************************************************************************/
-
-/* Includes ------------------------------------------------------------------*/
-#include <stdio.h>
-#include "amt630hv160_lib.h"
-
-/* PLL config ----------------------------------------------------------------*/
-#define CPUPLL_FREQ				800000000	//800M
-#define SYSPLL_FREQ				360000000	//360M
-#define DDRPLL_FREQ				360000000	//360M
-#define VPUPLL_FREQ				480000000	//480M
-#define MFCPLL_FREQ				360000000	//360M
-#define AHBPLL_FREQ				240000000	//240M
-#define GPUPLL_FREQ				500000000	//500M
-
-#define SYSPLL_SPRD_EN			0//1
-#define AHBPLL_SPRD_EN			0
-#define VPUPLL_SPRD_EN			1
-
-//spread spectrum permillage, for example: 5/10/20,范围越大,效果越好
-#define SYSPLL_SPRD_PERM		50	//50~500
-#define AHBPLL_SPRD_PERM		50	//50~500
-#define VPUPLL_SPRD_PERM		70	//30~500, < 70 屏幕不抖动
-//spread spectrum clock frequency,for example:40k/50k/60k
-#define SYSPLL_SPRD_FREQ		40000
-#define AHBPLL_SPRD_FREQ		40000
-#define VPUPLL_SPRD_FREQ		40000
-
-
-u32 CLK_GetPLLFreq(u32 pllcfg)
-{
-	u32 val;
-	u32 refdiv, fbdiv;
-	u32 postdiv1, postdiv2;
-
-	val = pllcfg;
-	refdiv = val & 0x3f;
-	fbdiv = (val >> 8) & 0xfff;
-	postdiv1 = (val >> 20) & 0x7;
-	postdiv2 = (val >> 23) & 0x7;
-
-	return HSE_Value / refdiv * fbdiv / postdiv1 / postdiv2;
-}
-
-u32 CLK_GetAHBFreq(void)
-{
-	u32 clksrc;
-
-	clksrc = (SYSCTRL->BUS_CLK_CFG >> 3) & 1;
-	if (clksrc)
-		return CLK_GetPLLFreq(SYSCTRL->AHBPLL_CFG);
-	else
-		return HSE_Value;
-}
-
-u32 CLK_GetAPBFreq(void)
-{
-	u32 div;
-
-	div = (SYSCTRL->BUS_CLK_CFG >> 4) & 3;
-	if (div > 2)
-		div = 2;
-	div = 1 << div;
-
-	return CLK_GetAHBFreq() / div;
-}
-
-static int CLK_SetSprd(u32 pllcfgreg)
-{
-	u64 clk, unit_freq;
-	u32 REFDIV, FBDIV, POSTDIV1, POSTDIV2, FBDIV1;
-	u32 max_offset, sprd_val, vco;
-	u32 val, mul, pllsprdcfgreg;
-	u32 sprd_perm, sprd_freq;
-
-	if (pllcfgreg == (u32)&SYSCTRL->SYSPLL_CFG) {
-		pllsprdcfgreg = (u32)&SYSCTRL->SYSPLL_SPRD_CTL;
-		sprd_perm = SYSPLL_SPRD_PERM;
-		sprd_freq = SYSPLL_SPRD_FREQ;
-	} else if (pllcfgreg == (u32)&SYSCTRL->AHBPLL_CFG) {
-		pllsprdcfgreg = (u32)&SYSCTRL->AHBPLL_SPRD_CTL;
-		sprd_perm = AHBPLL_SPRD_PERM;
-		sprd_freq = AHBPLL_SPRD_FREQ;
-	} else if (pllcfgreg == (u32)&SYSCTRL->VPUPLL_CFG) {
-		pllsprdcfgreg = (u32)&SYSCTRL->VPUPLL_SPRD_CTL;
-		sprd_perm = VPUPLL_SPRD_PERM;
-		sprd_freq = VPUPLL_SPRD_FREQ;
-	} else {
-		printf("The pll does not support sprd.\n");
-		return -1;
-	}
-
-	if(sprd_freq < 10000 || sprd_freq > 100000) {
-		printf("[%s], invalid freq config.\n", __func__);
-		return -1;
-	}
-
-	REFDIV = *(u32 *)pllcfgreg & 0x1f;
-	FBDIV = (*(u32 *)pllcfgreg >> 8) & 0xfff;
-	POSTDIV1 = (*(u32 *)pllcfgreg >> 20) & 0x7;
-	POSTDIV2 = (*(u32 *)pllcfgreg >> 23) & 0x7;
-
-	mul = HSE_Value / REFDIV / POSTDIV1 / POSTDIV2;
-	clk = CLK_GetPLLFreq(*(u32 *)pllcfgreg);
-	clk = clk + (clk * sprd_perm) / 1000;
-	FBDIV1 = clk / mul;
-
-	vco = HSE_Value / REFDIV * FBDIV1;
-	if (vco < 400000000 || vco > 1600000000) {
-		printf("sprd config abnormal.\n");
-		return -1;
-	}
-
-	max_offset = FBDIV1 - FBDIV;
-	if (!max_offset) {
-		printf("[%s], max_offset para except.\n", __func__);
-		return -1;
-	}
-
-	unit_freq = HSE_Value / 4 / REFDIV * FBDIV; //default 4
-	sprd_val = unit_freq / max_offset / 2 / sprd_freq;
-	if (sprd_val & ~(0xfff)) {
-		printf("[%s], sprd_val para except.\n", __func__);
-		return -1;
-	}
-
-	val = *(u32 *)pllsprdcfgreg;
-	//val &= ~(0x1 << 31);
-	val &= ~(0x1 << 30);
-	val &= ~(0xfff << 16);
-	val |= (max_offset & 0xfff) << 16;
-	val |= sprd_val & 0xfff;
-	*(u32 *)pllsprdcfgreg = val;
-	return 0;
-}
-
-void CLK_SetFreq(u32 pllcfgreg, u64 freq, u8 ensprd)
-{
-	u32 fbdiv, vco;
-	u32 postdiv2 = 1, postdiv1 = 2, refdiv = 3;				//满足PFD=8,12,24
-	u8 have_sprd = 0;
-
-	if (pllcfgreg == (u32)&SYSCTRL->SYSPLL_CFG) {			//360
-		SYSCTRL->SYSPLL_SPRD_CTL |= (1 << 30);
-		have_sprd = 1;
-	} else if (pllcfgreg == (u32)&SYSCTRL->AHBPLL_CFG) {	//240
-		SYSCTRL->AHBPLL_SPRD_CTL |= (1 << 30);
-		have_sprd = 1;
-	} else if (pllcfgreg == (u32)&SYSCTRL->VPUPLL_CFG) {	//480
-		SYSCTRL->VPUPLL_SPRD_CTL |= (1 << 30);
-		have_sprd = 1;
-	} else if (pllcfgreg == (u32)&SYSCTRL->CPUPLL_CFG) {	//800
-//		postdiv2 = 1;
-//		postdiv1 = 2;
-//		refdiv = 3;
-	} else if (pllcfgreg == (u32)&SYSCTRL->DDRPLL_CFG) {	//360
-//		postdiv2 = 1;
-//		postdiv1 = 2;
-//		refdiv = 3;
-	} else if (pllcfgreg == (u32)&SYSCTRL->MFCPLL_CFG) {	//360
-//		postdiv2 = 1;
-//		postdiv1 = 2;
-//		refdiv = 3;
-	} else if (pllcfgreg == (u32)&SYSCTRL->GPUPLL_CFG) {	//500
-//		postdiv2 = 1;
-//		postdiv1 = 2;
-//		refdiv = 3;
-	}
-
-	if (ensprd) {
-		//refdiv = 24;
-		if (!have_sprd) {
-			printf("This PLL does not have a spread support.\n");
-			refdiv = 3;
-			ensprd = 0;
-		}
-	}
-
-	/* POSTDIV1 should >= POSTDIV2 */
-	fbdiv = (freq * postdiv1 * postdiv2 * refdiv / HSE_Value) & 0xfff; //freq / 2
-	if (fbdiv < 16 || fbdiv > 320) {
-		printf("clock config error.\n");
-		while(1);
-	}
-
-	vco = HSE_Value / refdiv * fbdiv;
-	if (vco < 400000000 || vco > 1600000000) {
-		printf("clock config abnormal.\n");
-		while(1);
-	}
-
-	*(u32 *)pllcfgreg = (postdiv2 << 23) | (postdiv1 << 20) | (fbdiv << 8) | refdiv;
-	TIMER_Udelay(10);
-
-	if (ensprd) {
-		if (!CLK_SetSprd(pllcfgreg)) {
-			return;
-		}
-	}
-
-	*(u32 *)pllcfgreg |= (1 << 27);
-}
-
-void SYSCLK_Init(void)
-{
-	u32 timeout = 1000;
-
-	SYSCTRL->BUS_CLK_CFG &= ~0x3f;
-	SYSCTRL->DDR_CTL1_CFG &= ~0x3ffff;
-	SYSCTRL->AHBPLL_CFG |= 0xf << 26;
-	SYSCTRL->CPUPLL_CFG |= 0xf << 26;
-
-	CLK_SetFreq((u32)&SYSCTRL->AHBPLL_CFG, AHBPLL_FREQ, AHBPLL_SPRD_EN);
-	CLK_SetFreq((u32)&SYSCTRL->CPUPLL_CFG, CPUPLL_FREQ, 0);
-	CLK_SetFreq((u32)&SYSCTRL->SYSPLL_CFG, SYSPLL_FREQ, SYSPLL_SPRD_EN);
-	CLK_SetFreq((u32)&SYSCTRL->VPUPLL_CFG, VPUPLL_FREQ, VPUPLL_SPRD_EN);
-	CLK_SetFreq((u32)&SYSCTRL->DDRPLL_CFG, DDRPLL_FREQ, 0);
-	CLK_SetFreq((u32)&SYSCTRL->MFCPLL_CFG, MFCPLL_FREQ, 0);
-	CLK_SetFreq((u32)&SYSCTRL->GPUPLL_CFG, GPUPLL_FREQ, 0);
-
-	/* wait ahppll lock */
-	while (!(SYSCTRL->BOOT_SAMPLE & BOOT_SAMPLE_AHBPLL_LOCK) && timeout--)
-		TIMER_Udelay(1);
-
-	/* wait cpupll lock */
-	timeout = 1000;
-	while (!(SYSCTRL->BOOT_SAMPLE & BOOT_SAMPLE_CPUPLL_LOCK) && timeout--)
-		TIMER_Udelay(1);
-
-	/* wait syspll lock */
-	while (!(SYSCTRL->BOOT_SAMPLE & BOOT_SAMPLE_SYSPLL_LOCK) && timeout--)
-	TIMER_Udelay(1);
-
-	/* wait vpupll lock */
-	timeout = 1000;
-	while (!(SYSCTRL->BOOT_SAMPLE & BOOT_SAMPLE_VPUPLL_LOCK) && timeout--)
-	TIMER_Udelay(1);
-
-	/* wait ddrpll lock */
-	timeout = 1000;
-	while (!(SYSCTRL->BOOT_SAMPLE & BOOT_SAMPLE_DDRPLL_LOCK) && timeout--)
-	TIMER_Udelay(1);
-
-	/* wait mfcpll lock */
-	timeout = 1000;
-	while (!(SYSCTRL->BOOT_SAMPLE & BOOT_SAMPLE_MFCPLL_LOCK) && timeout--)
-	TIMER_Udelay(1);
-
-	/* wait gpupll lock */
-	timeout = 1000;
-	while (!(SYSCTRL->BOOT_SAMPLE & BOOT_SAMPLE_GPUPLL_LOCK) && timeout--)
-	TIMER_Udelay(1);
-
-	TIMER_Udelay(500);
-
-	/* apbpll clk en */
-	SYSCTRL->DDR_CTL1_CFG |= DDR_CTL1_AHBPLL_EN;
-
-	/* cpupll clk en */
-	SYSCTRL->DDR_CTL1_CFG |= DDR_CTL1_CPUPLL_EN;
-
-	/* syspll clk en */
-	SYSCTRL->DDR_CTL1_CFG |= DDR_CTL1_SYSPLL_EN;
-
-	/* vpupll clk en */
-	SYSCTRL->DDR_CTL1_CFG |= DDR_CTL1_VPUPLL_EN;
-
-	/* ddrpll clk en */
-	SYSCTRL->DDR_CTL1_CFG |= DDR_CTL1_DDRPLL_EN;
-
-	/* mfcpll clk en */
-	SYSCTRL->DDR_CTL1_CFG |= DDR_CTL1_MFCPLL_EN;
-
-	/* gpupll clk en */
-	SYSCTRL->DDR_CTL1_CFG |= DDR_CTL1_GPUPLL_EN;
-
-	/* switch hclk(mcu cpuclk is hclk) to ahbpll, pclk to hclk/2 */
-	SYSCTRL->BUS_CLK_CFG |= (1 << 4) | (1 << 3);
-
-	/* switch xclk to syspll, dclk to ddrpll, cclk to cpupll */
-	SYSCTRL->BUS_CLK_CFG |= (1 << 2) | (1 << 1 ) | (1 << 0);
-
-	TIMER_Udelay(10);
-}
-
-void SPI0_SetBusClk(u32 freq)
-{
-	u32 src_freq;
-	u32 div;
-	u32 val;
-	u32 clk_sel = 0;
-
-	//disable spi0 clk
-	SYSCTRL->BUS_CLK_EN &= ~(1 << 26);
-	SYSCTRL->PER_CLK_EN &= ~(1 << 0);
-	TIMER_Udelay(10);
-
-	val = SYSCTRL->CPUPLL_CFG;
-	//cpupll work
-	if (!((val >> 26) & 0x1) && (SYSCTRL->DDR_CTL1_CFG & DDR_CTL1_CPUPLL_EN)) {
-		src_freq = CLK_GetPLLFreq(val);
-		clk_sel = 1;
-		div = DIV_ROUND_UP(src_freq , freq);
-		if (div > 16) {
-			clk_sel = 0;
-			div = DIV_ROUND_UP(HSE_Value, freq);
-		}
-	} else {
-		div = DIV_ROUND_UP(HSE_Value, freq);
-	}
-
-	if (div > 16) {
-		printf("spi0 clk is too small, unsupported.\r\n");
-		return;
-	}
-
-	val = SYSCTRL->SSP_CLK_CFG;
-	val &= ~0x1f;
-	val |= (clk_sel << 4) | (div - 1);
-	SYSCTRL->SSP_CLK_CFG = val;
-
-	//enable spi0 clk
-	SYSCTRL->PER_CLK_EN |= 1 << 0;
-	SYSCTRL->BUS_CLK_EN |= 1 << 26;
-	TIMER_Udelay(10);
-}
-
-u32 SPI0_GetBusClk(void)
-{
-	u32 source_freq;
-	u32 div;
-
-	if (SYSCTRL->SSP_CLK_CFG & (1 << 4))
-		source_freq = CLK_GetPLLFreq(SYSCTRL->CPUPLL_CFG);
-	else
-		source_freq = HSE_Value;
-
-	div = (SYSCTRL->SSP_CLK_CFG & 0xf) + 1;
-
-	return source_freq / div;
-}
-
-void SPI1_SetBusClk(u32 freq)
-{
-	u32 src_freq;
-	u32 div;
-	u32 val;
-	u32 clk_sel = 0;
-
-	//disable spi1 clk
-	SYSCTRL->BUS_CLK_EN1 &= ~(1 << 2);
-	SYSCTRL->PER_CLK_EN &= ~(1 << 1);
-	TIMER_Udelay(10);
-
-	val = SYSCTRL->CPUPLL_CFG;
-	//cpupll work
-	if (!((val >> 26) & 0x1) && (SYSCTRL->DDR_CTL1_CFG & DDR_CTL1_CPUPLL_EN)) {
-		src_freq = CLK_GetPLLFreq(val);
-		clk_sel = 1;
-		div = DIV_ROUND_UP(src_freq, freq);
-		if (div > 16) {
-			clk_sel = 0;
-			div = DIV_ROUND_UP(HSE_Value, freq);
-		}
-	} else {
-		div = DIV_ROUND_UP(HSE_Value, freq);
-	}
-
-	if (div > 16) {
-		printf("spi1 clk is too small, unsupported.\r\n");
-		return;
-	}
-
-	val = SYSCTRL->SSP_CLK_CFG;
-	val &= ~(0x1f << 16);
-	val |= (clk_sel << 20) | ((div - 1) << 16);
-	SYSCTRL->SSP_CLK_CFG = val;
-
-	//enable spi1 clk
-	SYSCTRL->PER_CLK_EN |= 1 << 1;
-	SYSCTRL->BUS_CLK_EN1 |= 1 << 2;
-	TIMER_Udelay(10);
-
-}
-
-u32 SPI1_GetBusClk(void)
-{
-	u32 source_freq;
-	u32 div;
-
-	if (SYSCTRL->SSP_CLK_CFG & (1 << 20))
-		source_freq = CLK_GetPLLFreq(SYSCTRL->CPUPLL_CFG);
-	else
-		source_freq = HSE_Value;
-
-	div = ((SYSCTRL->SSP_CLK_CFG >> 16) & 0xf) + 1;
-
-	return source_freq / div;
-}
-
-void SDMMC0_SetBusClk(u32 freq)
-{
-	u32 src_freq;
-	u32 div;
-	u32 val;
-	u32 clk_sel = 0;
-
-	//disable sdmmc0 clk
-	SYSCTRL->BUS_CLK_EN &= ~(1 << 15);
-	SYSCTRL->PER_CLK_EN &= ~(1 << 15);
-	TIMER_Udelay(10);
-
-	val = SYSCTRL->AHBPLL_CFG;
-	//ahbpll work
-	if (!((val >> 26) & 0xf) && (SYSCTRL->DDR_CTL1_CFG & DDR_CTL1_AHBPLL_EN)) {
-		src_freq = CLK_GetPLLFreq(val);
-		clk_sel = 1;
-		div = DIV_ROUND_UP(src_freq, freq);
-		if (div > 32) {
-			clk_sel = 0;
-			src_freq = HSE_Value;
-			div = DIV_ROUND_UP(src_freq, freq);
-		}
-	} else {
-		src_freq = HSE_Value;
-		div = DIV_ROUND_UP(src_freq, freq);
-	}
-
-	if (div > 32) {
-		printf("sdmmc0 clk is too small, unsupported.\r\n");
-		return;
-	}
-
-	val = SYSCTRL->SDMMC_CLK_CFG;
-	val &= ~((0x3 << 6) | 0x1f);
-	val |= (clk_sel << 7) | (1 << 6) | (div - 1);
-	SYSCTRL->SDMMC_CLK_CFG = val;
-
-	//enable sdmmc0 clk
-	SYSCTRL->PER_CLK_EN |= 1 << 15;
-	SYSCTRL->BUS_CLK_EN |= 1 << 15;
-	TIMER_Udelay(10);
-}
-
-u32 SDMMC0_GetBusClk(void)
-{
-	u32 source_freq;
-	u32 div;
-
-	if (SYSCTRL->SDMMC_CLK_CFG & (1 << 7))
-		source_freq = CLK_GetPLLFreq(SYSCTRL->AHBPLL_CFG);
-	else
-		source_freq = HSE_Value;
-
-	if (SYSCTRL->SDMMC_CLK_CFG & (1 << 6)) {
-		div = (SYSCTRL->SDMMC_CLK_CFG & 0x1f) + 1;
-	} else {
-		div = 1;
-	}
-
-	return source_freq / div;
-}
-
-void SDMMC1_SetBusClk(u32 freq)
-{
-	u32 src_freq;
-	u32 div;
-	u32 val;
-	u32 clk_sel = 0;
-
-	//disable sdmmc1 clk
-	SYSCTRL->BUS_CLK_EN &= ~(1 << 16);
-	SYSCTRL->PER_CLK_EN &= ~(1 << 31);
-	TIMER_Udelay(10);
-
-	val = SYSCTRL->AHBPLL_CFG;
-	//ahbpll work
-	if (!((val >> 26) & 0xf) && (SYSCTRL->DDR_CTL1_CFG & DDR_CTL1_AHBPLL_EN)) {
-		src_freq = CLK_GetPLLFreq(val);
-		clk_sel = 1;
-		div = DIV_ROUND_UP(src_freq, freq);
-		if (div > 32) {
-			clk_sel = 0;
-			src_freq = HSE_Value;
-			div = DIV_ROUND_UP(src_freq, freq);
-		}
-	} else {
-		src_freq = HSE_Value;
-		div = DIV_ROUND_UP(src_freq, freq);
-	}
-
-	if (div > 32) {
-		printf("sdmmc0 clk is too small, unsupported.\r\n");
-		return;
-	}
-
-	val = SYSCTRL->SDMMC1_CLK_CFG;
-	val &= ~((0x3 << 6) | 0x1f);
-	val |= (clk_sel << 7) | (1 << 6) | (div - 1);
-	SYSCTRL->SDMMC1_CLK_CFG = val;
-
-	//enable sdmmc1 clk
-	SYSCTRL->PER_CLK_EN |= 1UL << 31;
-	SYSCTRL->BUS_CLK_EN |= 1 << 16;
-	TIMER_Udelay(10);
-}
-
-u32 SDMMC1_GetBusClk(void)
-{
-	u32 source_freq;
-	u32 div;
-
-	if (SYSCTRL->SDMMC1_CLK_CFG & (1 << 7))
-		source_freq = CLK_GetPLLFreq(SYSCTRL->AHBPLL_CFG);
-	else
-		source_freq = HSE_Value;
-
-	if (SYSCTRL->SDMMC1_CLK_CFG & (1 << 6)) {
-		div = (SYSCTRL->SDMMC1_CLK_CFG & 0x1f) + 1;
-	} else {
-		div = 1;
-	}
-
-	return source_freq / div;
-}
-
-void CANFD0_SetBusClk(u32 freq)
-{
-	u32 src_freq;
-	u32 div;
-	u32 val;
-	u32 clk_sel = 0;
-
-	//disable canfd0 clk
-	MCU_SYSCTRL->V6_PER_EN &= ~(1 << 0);
-	TIMER_Udelay(10);
-
-	val = SYSCTRL->AHBPLL_CFG;
-	//ahbpll work
-	if (!((val >> 26) & 0xf) && (SYSCTRL->DDR_CTL1_CFG & DDR_CTL1_CPUPLL_EN)) {
-		src_freq = CLK_GetPLLFreq(val);
-		clk_sel = 1;
-		div = DIV_ROUND_UP(src_freq , freq);
-		if (div > 32) {
-			clk_sel = 0;
-			div = DIV_ROUND_UP(HSE_Value, freq);
-		}
-	} else {
-		div = DIV_ROUND_UP(HSE_Value, freq);
-	}
-
-	if (div > 32) {
-		printf("canfd0 clk is too small, unsupported.\r\n");
-		return;
-	}
-
-	val = MCU_SYSCTRL->V6_CAN_CLK;
-	val &= ~0x3f;
-	val |= (clk_sel << 5) | (div - 1);
-	MCU_SYSCTRL->V6_CAN_CLK = val;
-
-	//enable canfd0 clk
-	MCU_SYSCTRL->V6_PER_EN |= 1 << 0;
-	TIMER_Udelay(10);
-
-}
-
-u32 CANFD0_GetBusClk(void)
-{
-	u32 source_freq;
-	u32 div;
-
-	if (MCU_SYSCTRL->V6_CAN_CLK & (1 << 5))
-		source_freq = CLK_GetPLLFreq(SYSCTRL->AHBPLL_CFG);
-	else
-		source_freq = HSE_Value;
-
-	div = (MCU_SYSCTRL->V6_CAN_CLK & 0x1f) + 1;
-
-	return source_freq / div;
-}
-
-void CANFD1_SetBusClk(u32 freq)
-{
-	u32 src_freq;
-	u32 div;
-	u32 val;
-	u32 clk_sel = 0;
-
-	//disable canfd1 clk
-	MCU_SYSCTRL->V6_PER_EN &= ~(1 << 1);
-	TIMER_Udelay(10);
-
-	val = SYSCTRL->AHBPLL_CFG;
-	//ahbpll work
-	if (!((val >> 26) & 0xf) && (SYSCTRL->DDR_CTL1_CFG & DDR_CTL1_CPUPLL_EN)) {
-		src_freq = CLK_GetPLLFreq(val);
-		clk_sel = 1;
-		div = DIV_ROUND_UP(src_freq , freq);
-		if (div > 32) {
-			clk_sel = 0;
-			div = DIV_ROUND_UP(HSE_Value, freq);
-		}
-	} else {
-		div = DIV_ROUND_UP(HSE_Value, freq);
-	}
-
-	if (div > 32) {
-		printf("canfd0 clk is too small, unsupported.\r\n");
-		return;
-	}
-
-	val = MCU_SYSCTRL->V6_CAN_CLK;
-	val &= ~(0x3f << 6);
-	val |= (clk_sel << 11) | ((div - 1) << 6);
-	MCU_SYSCTRL->V6_CAN_CLK = val;
-
-	//enable canfd1 clk
-	MCU_SYSCTRL->V6_PER_EN |= 1 << 1;
-	TIMER_Udelay(10);
-
-}
-
-u32 CANFD1_GetBusClk(void)
-{
-	u32 source_freq;
-	u32 div;
-
-	if (MCU_SYSCTRL->V6_CAN_CLK & (1 << 11))
-		source_freq = CLK_GetPLLFreq(SYSCTRL->AHBPLL_CFG);
-	else
-		source_freq = HSE_Value;
-
-	div = ((MCU_SYSCTRL->V6_CAN_CLK >> 6) & 0x1f) + 1;
-
-	return source_freq / div;
-}
-
-void ADC0_SetClk(u32 freq)
-{
-	u32 source_freq;
-	u32 div;
-
-	source_freq = HSE_Value;
-	div = DIV_ROUND_UP(source_freq , freq);
-
-	div = div / 2 - 1;
-	if (div > 0x7fff)
-		div = 0x7fff;
-
-	SYSCTRL->TIMER_CLK_CFG &= ~(0x7fff << 16);
-	SYSCTRL->TIMER_CLK_CFG |= (div << 16);
-}
-
-u32 ADC0_GetClk(void)
-{
-	u32 source_freq;
-	u32 div;
-
-	source_freq = HSE_Value;
-	div = (((SYSCTRL->TIMER_CLK_CFG >> 16) & 0x7fff) + 1) * 2;
-
-	return source_freq / div;
-}
-
-void ADC1_SetClk(u32 freq)
-{
-	u32 source_freq;
-	u32 div;
-
-	source_freq = HSE_Value;
-	div = DIV_ROUND_UP(source_freq , freq);
-
-	div = div / 2 - 1;
-	if (div > 0x7fff)
-		div = 0x7fff;
-
-	SYSCTRL->ADC_CLK1_CFG &= ~(0x7fff << 0);
-	SYSCTRL->ADC_CLK1_CFG |= (div << 0);
-}
-
-u32 ADC1_GetClk(void)
-{
-	u32 source_freq;
-	u32 div;
-
-	source_freq = HSE_Value;
-	div = (((SYSCTRL->ADC_CLK1_CFG >> 0) & 0x7fff) + 1) * 2;
-
-	return source_freq / div;
-}
-
-void ADC2_SetClk(u32 freq)
-{
-	u32 source_freq;
-	u32 div;
-
-	source_freq = HSE_Value;
-	div = DIV_ROUND_UP(source_freq , freq);
-
-	div = div / 2 - 1;
-	if (div > 0x7fff)
-		div = 0x7fff;
-
-	SYSCTRL->ADC_CLK1_CFG &= ~(0x7fff << 16);
-	SYSCTRL->ADC_CLK1_CFG |= (div << 16);
-}
-
-u32 ADC2_GetClk(void)
-{
-	u32 source_freq;
-	u32 div;
-
-	source_freq = HSE_Value;
-	div = (((SYSCTRL->ADC_CLK1_CFG >> 16) & 0x7fff) + 1) * 2;
-
-	return source_freq / div;
-}
-
-void PWM_SetClk(u32 freq)
-{
-	u32 src_freq;
-	u32 div;
-	u32 val;
-	u32 clk_sel = 0;
-
-	val = SYSCTRL->SYSPLL_CFG;
-	//syspll work
-	if (!((val >> 26) & 0x1) && (SYSCTRL->DDR_CTL1_CFG & DDR_CTL1_SYSPLL_EN)) {
-		src_freq = CLK_GetPLLFreq(val);
-		clk_sel = 1;
-		div = DIV_ROUND_UP(src_freq , freq);
-		if (div > 16) {
-			clk_sel = 0;
-			div = DIV_ROUND_UP(HSE_Value, freq);
-		}
-	} else {
-		div = DIV_ROUND_UP(HSE_Value, freq);
-	}
-
-	if (div > 16) {
-		printf("pwm clk is too small, unsupported.\r\n");
-		return;
-	}
-
-	val = SYSCTRL->PER_CLK_CFG;
-	val &= ~(0x1f << 4);
-	val |= ((clk_sel << 4) | (div - 1)) << 4;
-	SYSCTRL->PER_CLK_CFG = val;
-}
-
-u32 PWM_GetClk(void)
-{
-	u32 source_freq;
-	u32 div;
-
-	if (SYSCTRL->PER_CLK_CFG & (1 << 8))
-		source_freq = CLK_GetPLLFreq(SYSCTRL->SYSPLL_CFG);
-	else
-		source_freq = HSE_Value;
-
-	div = ((SYSCTRL->PER_CLK_CFG >> 4) & 0xf) + 1;
-
-	return source_freq / div;
-}

+ 6 - 1
amt630hv160-mcu/amt630hv160-mcu-sram-nos/src/ArkmicroFiles/libcpu-amt630hv160/source/amt630hv160_adc.c

@@ -63,6 +63,7 @@ static u32 adc_get_clk(ADC_TypeDef *adc)
 	return clk;
 }
 
+#if 0
 static void adc_set_clk(ADC_TypeDef *adc, u32 freq)
 {
 #ifdef _ADC0
@@ -86,6 +87,7 @@ static void adc_set_clk(ADC_TypeDef *adc, u32 freq)
 		printf("%s set adc clk fail!\n", __func__);
 	}
 }
+#endif
 
 static adc_pdata_t *adc_get_prv_data(ADC_TypeDef *adc)
 {
@@ -271,6 +273,7 @@ void ADC2_IRQHandler(void)
 ///*
 // * high = 1时阈值约等于 1.6v(ADC电源为1.8v时);
 // * high = 0时阈值约定于 0.2v(ADC电源为1.8v时);
+// * 该函数如果要使用的话需放到adc_hardware_init内调用
 // */
 //int adc_int_threshold_sel(ADC_TypeDef *adc, int high)
 //{
@@ -435,14 +438,17 @@ void adc_hardware_init(void)
 		由于原厂开发板中每个ADC的8个管脚并联,导致必须将8个管脚都设为输入才能正常触发ADC
 	*/
 #ifdef _ADC0
+	ADC0_SetClk(ADC_CLK_FREQ);
 	writel(readl(0x50900184) | (0xff << 15), 0x50900184);
 #endif /*_ADC0 */
 
 #ifdef _ADC1
+	ADC1_SetClk(ADC_CLK_FREQ);
 	writel(readl(0x50900184) | (0xff << 23), 0x50900184);
 #endif /*_ADC1 */
 
 #ifdef _ADC2
+	ADC2_SetClk(ADC_CLK_FREQ);
 	GPIO_DirectionInput(ADC_CH_AUX0 + 111);
 	GPIO_DirectionInput(ADC_CH_AUX1 + 111);
 	GPIO_DirectionInput(ADC_CH_AUX2 + 111);
@@ -464,7 +470,6 @@ int adc_init(ADC_TypeDef *adc)
 		return -1;
 	}
 
-	adc_set_clk(adc, ADC_CLK_FREQ);
 	adc_reset(adc);
 
 	adc_prv = adc_get_prv_data(adc);

+ 76 - 7
amt630hv160-mcu/amt630hv160-mcu-sram-nos/src/ArkmicroFiles/libcpu-amt630hv160/source/amt630hv160_clk.c

@@ -35,7 +35,18 @@
 #define AHBPLL_SPRD_FREQ		20000	//20k~100k
 #define VPUPLL_SPRD_FREQ		20000	//20k~100k
 
+static u32 ahb_clk_freq;
+static u32 apb_clk_freq;
+static u32 adc0_clk_freq;
+static u32 adc1_clk_freq;
+static u32 adc2_clk_freq;
+static u32 pwm_clk_freq;
 
+/*
+ * 由于暂未对SYSCTRL模块实现互斥访问逻辑,CPU起来后MCU端访问不了SYSCTRL,
+ * 因此该函数只能在StartCpu函数调用前使用,其他涉及SYSCTRL寄存器访问的函数也一样。
+ * CLK_GetAHBFreq,CLK_GetAPBFreq,ADCX_GetClk,PWM_GetClk这些特殊处理过的函数除外
+ */
 u32 CLK_GetPLLFreq(u32 pllcfg)
 {
 	u32 val;
@@ -55,23 +66,33 @@ u32 CLK_GetAHBFreq(void)
 {
 	u32 clksrc;
 
+	if (ahb_clk_freq)
+		return ahb_clk_freq;
+
 	clksrc = (SYSCTRL->BUS_CLK_CFG >> 3) & 1;
 	if (clksrc)
-		return CLK_GetPLLFreq(SYSCTRL->AHBPLL_CFG);
+		ahb_clk_freq = CLK_GetPLLFreq(SYSCTRL->AHBPLL_CFG);
 	else
-		return HSE_Value;
+		ahb_clk_freq = HSE_Value;
+
+	return ahb_clk_freq;
 }
 
 u32 CLK_GetAPBFreq(void)
 {
 	u32 div;
 
+	if (apb_clk_freq)
+		return apb_clk_freq;
+
 	div = (SYSCTRL->BUS_CLK_CFG >> 4) & 3;
 	if (div > 2)
 		div = 2;
 	div = 1 << div;
 
-	return CLK_GetAHBFreq() / div;
+	apb_clk_freq = CLK_GetAHBFreq() / div;
+
+	return apb_clk_freq;
 }
 
 /*
@@ -282,6 +303,11 @@ void SYSCLK_Init(void)
 	SYSCTRL->BUS_CLK_CFG |= (1 << 2) | (1 << 1 ) | (1 << 0);
 
 	TIMER_Udelay(10);
+
+	//此处代码用于CPU起来前访问SYSCTRL获取时钟,不能注释
+	ahb_clk_freq = CLK_GetAHBFreq();
+	apb_clk_freq = CLK_GetAPBFreq();
+	pwm_clk_freq = PWM_GetClk();
 }
 
 void SPI0_SetBusClk(u32 freq)
@@ -642,6 +668,9 @@ void ADC0_SetClk(u32 freq)
 	u32 source_freq;
 	u32 div;
 
+	if (cpu_running)
+		return;
+
 	source_freq = HSE_Value;
 	div = DIV_ROUND_UP(source_freq , freq);
 
@@ -651,6 +680,8 @@ void ADC0_SetClk(u32 freq)
 
 	SYSCTRL->TIMER_CLK_CFG &= ~(0x7fff << 16);
 	SYSCTRL->TIMER_CLK_CFG |= (div << 16);
+
+	adc0_clk_freq = source_freq / ((div + 1) * 2);
 }
 
 u32 ADC0_GetClk(void)
@@ -658,10 +689,15 @@ u32 ADC0_GetClk(void)
 	u32 source_freq;
 	u32 div;
 
+	if (adc0_clk_freq)
+		return adc0_clk_freq;
+
 	source_freq = HSE_Value;
 	div = (((SYSCTRL->TIMER_CLK_CFG >> 16) & 0x7fff) + 1) * 2;
 
-	return source_freq / div;
+	adc0_clk_freq = source_freq / div;
+
+	return adc0_clk_freq;
 }
 
 void ADC1_SetClk(u32 freq)
@@ -669,6 +705,9 @@ void ADC1_SetClk(u32 freq)
 	u32 source_freq;
 	u32 div;
 
+	if (cpu_running)
+		return;
+
 	source_freq = HSE_Value;
 	div = DIV_ROUND_UP(source_freq , freq);
 
@@ -678,6 +717,8 @@ void ADC1_SetClk(u32 freq)
 
 	SYSCTRL->ADC_CLK1_CFG &= ~(0x7fff << 0);
 	SYSCTRL->ADC_CLK1_CFG |= (div << 0);
+
+	adc1_clk_freq = source_freq / ((div + 1) * 2);
 }
 
 u32 ADC1_GetClk(void)
@@ -685,10 +726,15 @@ u32 ADC1_GetClk(void)
 	u32 source_freq;
 	u32 div;
 
+	if (adc1_clk_freq)
+		return adc1_clk_freq;
+
 	source_freq = HSE_Value;
 	div = (((SYSCTRL->ADC_CLK1_CFG >> 0) & 0x7fff) + 1) * 2;
 
-	return source_freq / div;
+	adc1_clk_freq = source_freq / div;
+
+	return adc1_clk_freq;
 }
 
 void ADC2_SetClk(u32 freq)
@@ -696,6 +742,9 @@ void ADC2_SetClk(u32 freq)
 	u32 source_freq;
 	u32 div;
 
+	if (cpu_running)
+		return;
+
 	source_freq = HSE_Value;
 	div = DIV_ROUND_UP(source_freq , freq);
 
@@ -705,6 +754,8 @@ void ADC2_SetClk(u32 freq)
 
 	SYSCTRL->ADC_CLK1_CFG &= ~(0x7fff << 16);
 	SYSCTRL->ADC_CLK1_CFG |= (div << 16);
+
+	adc2_clk_freq = source_freq / ((div + 1) * 2);
 }
 
 u32 ADC2_GetClk(void)
@@ -712,10 +763,15 @@ u32 ADC2_GetClk(void)
 	u32 source_freq;
 	u32 div;
 
+	if (adc2_clk_freq)
+		return adc2_clk_freq;
+
 	source_freq = HSE_Value;
 	div = (((SYSCTRL->ADC_CLK1_CFG >> 16) & 0x7fff) + 1) * 2;
 
-	return source_freq / div;
+	adc2_clk_freq = source_freq / div;
+
+	return adc2_clk_freq;
 }
 
 void PWM_SetClk(u32 freq)
@@ -725,6 +781,9 @@ void PWM_SetClk(u32 freq)
 	u32 val;
 	u32 clk_sel = 0;
 
+	if (cpu_running)
+		return;
+
 	val = SYSCTRL->SYSPLL_CFG;
 	//syspll work
 	if (SYSCTRL->DDR_CTL1_CFG & DDR_CTL1_SYSPLL_EN) {
@@ -748,6 +807,11 @@ void PWM_SetClk(u32 freq)
 	val &= ~(0x1f << 4);
 	val |= ((clk_sel << 4) | (div - 1)) << 4;
 	SYSCTRL->PER_CLK_CFG = val;
+
+	if (clk_sel)
+		pwm_clk_freq = src_freq / div;
+	else
+		pwm_clk_freq = HSE_Value / div;
 }
 
 u32 PWM_GetClk(void)
@@ -755,6 +819,9 @@ u32 PWM_GetClk(void)
 	u32 source_freq;
 	u32 div;
 
+	if (pwm_clk_freq)
+		return pwm_clk_freq;
+
 	if (SYSCTRL->PER_CLK_CFG & (1 << 8))
 		source_freq = CLK_GetPLLFreq(SYSCTRL->SYSPLL_CFG);
 	else
@@ -762,5 +829,7 @@ u32 PWM_GetClk(void)
 
 	div = ((SYSCTRL->PER_CLK_CFG >> 4) & 0xf) + 1;
 
-	return source_freq / div;
+	pwm_clk_freq = source_freq / div;
+
+	return pwm_clk_freq;
 }