?? hal_mcg.c
字號:
/*
* 測試硬件平臺:LPLD_K60 Card
* 版權(quán)所有:北京拉普蘭德電子技術(shù)有限公司
* 網(wǎng)絡(luò)銷售:http://laplenden.taobao.com
* 公司門戶:http://www.lpld.cn
*
* 文件名: HAL_MCG.h
* 用途: MCG底層模塊相關(guān)函數(shù)
* 最后修改日期: 20120216
*
* 開發(fā)者使用協(xié)議:
* 本代碼面向所有使用者開放源代碼,開發(fā)者可以隨意修改源代碼。但本段及以上注釋應(yīng)
* 予以保留,不得更改或刪除原版權(quán)所有者姓名。二次開發(fā)者可以加注二次版權(quán)所有者,
* 但應(yīng)在遵守此協(xié)議的基礎(chǔ)上,開放源代碼、不得出售代碼本身。
*
* 說明:本頁代碼基于Freescale官方示例代碼修改,源代碼文件為 mcg.c
*/
#include "common.h"
#include "HAL_MCG.h"
/*
* LPLD_PLL_Setup
* PLL初始化內(nèi)核及其他系統(tǒng)時鐘
*
* 參數(shù):
* clk_option--期望內(nèi)核時鐘頻率
* |__PLLx--參見HAL_MCG.h中的PLL_option定義
*
* 輸出:
* 內(nèi)核頻率,單位MHz
*/
unsigned char LPLD_PLL_Setup(unsigned char pll_option)
{
unsigned char pll_freq;
unsigned char prdiv;
if(pll_option<111)
{
prdiv = 24;
}
else if(pll_option<201)
{
prdiv = 12;
}
else if(pll_option<221)
{
prdiv = 11;
}
else
{
return 0;
}
// 這里假設(shè)復(fù)位后 MCG 模塊默認為 FEI 模式
// 首先移動到 FBE 模式
// 使能外部 resonator(振蕩器), RANGE=2, HGO=1, EREFS=1, LP=0, IRCS=0
MCG_C2 = MCG_C2_RANGE(2) | MCG_C2_HGO_MASK | MCG_C2_EREFS_MASK;
// 振蕩器初始化完成后,釋放鎖存狀態(tài)下的 oscillator 和 GPIO
SIM_SCGC4 |= SIM_SCGC4_LLWU_MASK;
LLWU_CS |= LLWU_CS_ACKISO_MASK;
// 選擇外部 oscilator 、參考分頻器 and 清零 IREFS 啟動外部osc
// CLKS=2, FRDIV=3, IREFS=0, IRCLKEN=0, IREFSTEN=0
MCG_C1 = MCG_C1_CLKS(2) | MCG_C1_FRDIV(5);
while (!(MCG_S & MCG_S_OSCINIT_MASK)){}; // 等待 oscillator 初始化
while (MCG_S & MCG_S_IREFST_MASK){}; // 等待參考時鐘清零
while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x2){}; // 等待時鐘狀態(tài)顯示為外部參考時鐘(ext ref clk)
// 進入FBE模式
// 配置 PLL 參考分頻器, PLLCLKEN=0, PLLSTEN=0, PRDIV=5
// 用晶振頻率來選擇 PRDIV 值. 僅在有頻率晶振的時候支持
// 產(chǎn)生 2MHz 的參考時鐘給 PLL.
MCG_C5 = MCG_C5_PRDIV(prdiv); // 設(shè)置 PLL 匹配晶振的參考分頻數(shù)
// 確保MCG_C6處于復(fù)位狀態(tài),禁止LOLIE、PLL、和時鐘控制器,清PLL VCO分頻器
MCG_C6 = 0x0;
// 選擇PLL VCO分頻器,系統(tǒng)時鐘分頻器取決于時鐘選項
switch (pll_option) {
case 60:
// 設(shè)置系統(tǒng)選項分頻
// MCG=PLL, core = MCG, bus = MCG/2, FlexBus = MCG/2, Flash clock= MCG/3
LPLD_Set_SYS_DIV(0,1,1,2); //core=60M, bus=30M, FlexBus=30M, Flash Clk=20M
// 設(shè)置 VCO 分頻并使能 50MHz PLL, LOLIE=0, PLLS=1, CME=0, VDIV=1
MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV(6); //VDIV = 6 (2x30) 60MHz
pll_freq = 60;
break;
case 70:
LPLD_Set_SYS_DIV(0,1,1,2); //core=70M, bus=35M, FlexBus=35M, Flash Clk=23.3M
MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV(11); //VDIV = 11 (2x35) 70MHz
pll_freq = 70;
break;
case 80:
LPLD_Set_SYS_DIV(0,1,1,3); //core=80M, bus=40M, FlexBus=40M, Flash Clk=20M
MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV(16); //VDIV = 16 (2x40) 80MHz
pll_freq = 80;
break;
case 90:
LPLD_Set_SYS_DIV(0,1,1,3); //core=90M, bus=45M, FlexBus=45M, Flash Clk=22.5M
MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV(21); //VDIV = 21 (2x45) 90MHz
pll_freq = 90;
break;
case 100:
LPLD_Set_SYS_DIV(0,1,1,3); //core=100M, bus=50M, FlexBus=50M, Flash Clk=25M
MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV(26); //VDIV = 26 (2x50) 100MHz
pll_freq = 100;
break;
case 110:
LPLD_Set_SYS_DIV(0,2,2,4); //core=110M, bus=36.7M, FlexBus=36.7M, Flash Clk=22M
MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV(31); //VDIV = 31 (2x55) 110MHz
pll_freq = 110;
break;
case 120:
LPLD_Set_SYS_DIV(0,2,2,4); //core=120M, bus=40M, FlexBus=40M, Flash Clk=24M
MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV(7); //VDIV = 7 (3.846x31) 119.2MHz
pll_freq = 120;
break;
case 130:
LPLD_Set_SYS_DIV(0,2,2,5); //core=130M, bus=43M, FlexBus=43M, Flash Clk=21.6M
MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV(10); //VDIV = 10 (3.846x34) 130.8MHz
pll_freq = 130;
break;
case 150:
LPLD_Set_SYS_DIV(0,2,2,5); //core=150M, bus=50M, FlexBus=50M, Flash Clk=25M
MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV(15); //VDIV = 15 (3.846x39) 150MHz
pll_freq = 150;
break;
case 170:
LPLD_Set_SYS_DIV(0,3,3,6); //core=170M, bus=42.5M, FlexBus=42.5M, Flash Clk=24.3M
MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV(20); //VDIV = 20 (3.846x44) 169.2MHz
pll_freq = 170;
break;
case 180:
LPLD_Set_SYS_DIV(0,3,3,7); //core=180M, bus=45M, FlexBus=45M, Flash Clk=22.5M
MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV(23); //VDIV = 23 (3.846x47) 180.8MHz
pll_freq = 180;
break;
case 200:
LPLD_Set_SYS_DIV(0,3,3,7); //core=200M, bus=50M, FlexBus=50M, Flash Clk=25M
MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV(28); //VDIV = 28 (3.846x52) 200MHz
pll_freq = 200;
break;
case 209:
LPLD_Set_SYS_DIV(0,4,4,8); //core=209M, bus=42M, FlexBus=42M, Flash Clk=23.2M
MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV(26); //VDIV = 26 (4.17x50) 208.5MHz
pll_freq = 209;
break;
}
while (!(MCG_S & MCG_S_PLLST_MASK)){}; // wait for PLL status bit to set
while (!(MCG_S & MCG_S_LOCK_MASK)){}; // Wait for LOCK bit to set
// 已經(jīng)進入PBE模式
// Transition into PEE by setting CLKS to 0
// CLKS=0, FRDIV=3, IREFS=0, IRCLKEN=0, IREFSTEN=0
MCG_C1 &= ~MCG_C1_CLKS_MASK;
// Wait for clock status bits to update
while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x3){};
// 已經(jīng)進入PEE模式
return pll_freq;
}
/*
* LPLD_Set_SYS_DIV
* 設(shè)置系統(tǒng)始終分頻(FSCL官方代碼)
*
* 說明:
* 這段代碼必須放置在RAM中. It is a workaround for errata e2448.
* 當Flash時鐘分頻改變的時候,F(xiàn)lash預(yù)讀取必須禁用.
* 當正在從Flash執(zhí)行的時候這里不能執(zhí)行.
* 在預(yù)讀取被重新使能之前必須在時鐘分頻改變后有一段小的延時.
*
* 參數(shù):
* outdiv1~outdiv4--分別為core, bus, FlexBus, Flash時鐘分頻系數(shù)
*/
#if (defined(IAR))
__ramfunc void LPLD_Set_SYS_DIV(uint32 outdiv1, uint32 outdiv2, uint32 outdiv3, uint32 outdiv4)
#elif (defined(CW))
__relocate_code__
void LPLD_Set_SYS_DIV(uint32 outdiv1, uint32 outdiv2, uint32 outdiv3, uint32 outdiv4)
#endif
{
uint32 temp_reg;
uint8 i;
temp_reg = FMC_PFAPR; // 備份 FMC_PFAPR 寄存器
// 設(shè)置 M0PFD 到 M7PFD 為 1 禁用預(yù)先讀取
FMC_PFAPR |= FMC_PFAPR_M7PFD_MASK | FMC_PFAPR_M6PFD_MASK | FMC_PFAPR_M5PFD_MASK
| FMC_PFAPR_M4PFD_MASK | FMC_PFAPR_M3PFD_MASK | FMC_PFAPR_M2PFD_MASK
| FMC_PFAPR_M1PFD_MASK | FMC_PFAPR_M0PFD_MASK;
// 設(shè)置時鐘分頻為期望值
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(outdiv1) | SIM_CLKDIV1_OUTDIV2(outdiv2)
| SIM_CLKDIV1_OUTDIV3(outdiv3) | SIM_CLKDIV1_OUTDIV4(outdiv4);
// 延時一小段時間等待改變
for (i = 0 ; i < outdiv4 ; i++)
{}
FMC_PFAPR = temp_reg; // 回復(fù)原先的 FMC_PFAPR 寄存器值
return;
} // set_sys_dividers
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -