📄 tm_clk.c
字号:
#include "../inc/def.h"
#include "../inc/config.h"
#include "../inc/board.h"
#include "../inc/utils.h"
#include "../inc/slib.h"
#include "2410addr.h"
#define EXT_OSC_CLK 12000000
static struct{
U32 mclk;
U32 pclk;
U32 sclk;
U32 freq;
} ClkPara;
static U32 clk_div_val;
static void ChangeClockDivider(void)
{
// hdivn,pdivn FCLK:HCLK:PCLK
// 0,0 1:1:1
// 0,1 1:1:2
// 1,0 1:2:2
// 1,1 1:2:4
rCLKDIVN = clk_div_val ;//(hclk_div<<1) | pclk_div;
if(clk_div_val&2)
MMU_SetAsyncBusMode();
else
MMU_SetFastBusMode();
}
static void set_pll(void)
{
// U32 i, j;
U32 old_freq;
if(ClkPara.mclk>255)
ClkPara.mclk = 255;
if(ClkPara.pclk>63)
ClkPara.pclk = 63;
if(ClkPara.sclk>3)
ClkPara.sclk = 3;
/* if(!ClkPara.mclk) {
ClkPara.mclk = 172;
ClkPara.pclk = 4;
ClkPara.sclk = 1;
}*/
// j = ClkPara.sclk;
// i = 1;
// while(j--)
// i *= 2;
old_freq = ClkPara.freq;
ClkPara.freq = (EXT_OSC_CLK*(ClkPara.mclk+8))/((ClkPara.pclk+2)<<ClkPara.sclk);
if((ClkPara.freq>=270000000)||(ClkPara.freq<5*EXT_OSC_CLK)) {
ClkPara.mclk = 192;
ClkPara.pclk = 4;
ClkPara.sclk = 1;
ClkPara.freq = EXT_OSC_CLK*180U/12U;
}
clk_div_val = 0;
if(ClkPara.freq>=80000000) {
if(ClkPara.freq>=120000000) {
clk_div_val |= 2;
if(ClkPara.freq>=160000000)
clk_div_val |= 1;
} else
clk_div_val |= 1; //80~120MHz
}
if(old_freq<ClkPara.freq)
ChangeClockDivider();
rMPLLCON = (ClkPara.mclk << 12) | (ClkPara.pclk << 4) | ClkPara.sclk;
ChangeClockDivider();
}
void SystemClockInit(void)
{
ClkPara.mclk = 192;
ClkPara.pclk = 4;
ClkPara.sclk = 1;
set_pll();
}
U32 GetCpuClock(void)
{
return ClkPara.freq;
}
U32 GetMasterClock(void)
{
U32 clk;
clk = GetCpuClock();
if(rCLKDIVN&2)
clk >>= 1;
if(rCLKDIVN&1)
clk >>= 1;
return clk;
}
int SetSysClock(void)
{
int mdiv, pdiv, sdiv;
char tmp[4];
printf("Please enter the PLL parameter to use, mdiv[0-255], pdiv[0-63], sdiv[0-3]\n");
printf("mdiv: ");
if((mdiv=strtodec(tmp, GetParameter(tmp, 3)))<0) {
printf("\nget mdiv Error!\n");
return -1;
}
printf("\npdiv: ");
if((pdiv=strtodec(tmp, GetParameter(tmp, 2)))<0) {
printf("\nget pdiv Error!\n");
return -1;
}
printf("\nsdiv: ");
if((sdiv=strtodec(tmp, GetParameter(tmp, 1)))<0) {
printf("\nget sdiv Error!\n");
return -1;
}
printf("\nYou set System clock mdiv = %d, pdiv = %d, sdiv = %d\n", mdiv, pdiv, sdiv);
Delay(100);
ClkPara.mclk = mdiv;
ClkPara.pclk = pdiv;
ClkPara.sclk = sdiv;
set_pll();
return 0;
}
U32 GetSysClock(SysClock pSysClock[])
{
pSysClock[0].name = "CPU";
pSysClock[0].freq = GetCpuClock();
pSysClock[1].name = "HCLK";
pSysClock[1].freq = GetCpuClock()>>((rCLKDIVN&2)>>1);
pSysClock[2].name = "PCLK";
pSysClock[2].freq = GetMasterClock();
return 3;
}
void SetSysClockPara(void *addr)
{
U32 *pData = addr;
ClkPara.mclk = pData[0];
ClkPara.pclk = pData[1];
ClkPara.sclk = pData[2];
set_pll();
}
void GetSysClockPara(void *addr)
{
U32 *pData = addr;
pData[0] = ClkPara.mclk;
pData[1] = ClkPara.pclk;
pData[2] = ClkPara.sclk;
pData[3] = ClkPara.freq;
}
void TimerInit(U32 HZ)
{
rTCFG0 &= 0xffff00ff;
rTCFG0 |= 1<<8; //1/2 prescaler
rTCFG1 &= 0xfff0ffff;
rTCFG1 |= 3<<16; //mux = 1/16
rTCNTB4 = GetMasterClock()/( HZ*2*16 ) - 1 ;
rTCON &= 0xff0fffff; //stop Timer4
rTCON |= 0x00700000; //auto-reload, update TCNTB4, start Timer4
rTCON &= 0xffdfffff;
}
/*void ResetTimer(void)
{
rTCON &= ~(1<<20);
rTCON |= (1<<20);
}*/
void Delay(U32 ms)
{
U16 i;
i = rTCNTB4>>1; //1000us/2
rTCON &= ~(1<<20);
rTCON |= (1<<20); //停止再启动,重装初值,减计数
while(ms--) {
while(rTCNTO4>=i);
while(rTCNTO4<i);
}
}
int WaitEventWithTimeout(int (*event)(void), int cond, U32 ms)
{
int result;
U16 half, ms_h;
half = rTCNTB4>>1; //1000us/2
rTCON &= ~(1<<20);
rTCON |= (1<<20); //停止再启动,重装初值,减计数
ms_h = 0;
while(ms) {
result = (*event)();
if(cond) {
if(result)
return 0;
} else {
if(!result)
return 0;
}
if(!ms_h) {
if(rTCNTO4<=half)
ms_h = 1;
} else {
if(rTCNTO4>half) {
ms_h = 0;
ms--;
}
}
}
return -1;
}
/*************************************************************/
#define RTC_RW_EN() (rRTCCON = 1) //|= 1
#define RTC_RW_DS() (rRTCCON &= ~1)
void RtcSetDay(TIME_STRUC *time)
{
RTC_RW_EN(); //RTC读写使能,选择BCD时钟、计数器,无复位,1/32768
rBCDYEAR = time->year&0xff; //年
rBCDMON = time->month; //月
rBCDDATE = time->day; //日
RTC_RW_DS();
}
void RtcSetWeek(TIME_STRUC *time)
{
RTC_RW_EN();
rBCDDAY = time->weekday;
RTC_RW_DS();
}
void RtcSetTime(TIME_STRUC *time)
{
RTC_RW_EN(); //RTC读写使能,选择BCD时钟、计数器,无复位,1/32768
rBCDHOUR = time->hour; //小时
rBCDMIN = time->min; //分
rBCDSEC = time->sec; //秒
RTC_RW_DS();
}
void RtcGetTime(TIME_STRUC *time)
{
unsigned char m;
// RTC_RW_EN(); //RTC读写使能
time->year = 0x2000 + rBCDYEAR;
time->weekday = rBCDDAY;
m = rBCDMON;
time->month = m;//(m>>4)*10 + (m&0xf); //BCD码转十进制
m = rBCDDATE;
time->day = m;//(m>>4)*10 + (m&0xf); //BCD码转十进制
m = rBCDHOUR;
time->hour = m;//(m>>4)*10 + (m&0xf); //BCD码转十进制
m = rBCDMIN;
time->min = m;//(m>>4)*10 + (m&0xf); //BCD码转十进制
m = rBCDSEC;
time->sec = m;//(m>>4)*10 + (m&0xf); //BCD码转十进制
// RTC_RW_DS(); //RTC读写禁止(降低功率消耗),选择BCD时钟、计数器,无复位,1/32768
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -