ARM裸機之CLOCK

聲明:本文由個人學習過程中整理而成,轉載請註明出處。


1、什麼是時鐘?SoC爲什麼需要時鐘?

(1)生活中時鐘是用來記錄時間的,而在SOC中時鐘代表了一種同步的節拍。

(2)SOC中的各部件在時鐘系統的作用下協同工作。


2、時鐘一般如何獲得

(1)外部輸入時鐘信號,SOC通過引腳從外部輸入時鐘信號。

(2)外部晶體振盪器+內部時鐘發生器產生時鐘信號。

(3)外部晶體振盪器+內部時鐘發生器+內部PLL產生高頻時鐘+內部分頻器(各部件都有自己的分頻器)產生各種頻率時鐘。


3、時鐘設置步驟:

(1)、暫不使用PLL。

(2)、設置鎖定時間,使用默認值即可。

(3)、設置PLL倍頻後的目標值。

(4)、設置分頻

(5)、設置各種PLL的MUX,使用PLL。


4、彙編代碼實現

#define ELFIN_CLOCK_POWER_BASE0xE0100000


#define APLL_LOCK_OFFSET0x00

#define MPLL_LOCK_OFFSET0x08


#define APLL_CON0_OFFSET0x100

#define APLL_CON1_OFFSET0x104

#define MPLL_CON_OFFSET0x108


#define CLK_SRC0_OFFSET0x200

#define CLK_SRC1_OFFSET0x204

#define CLK_SRC2_OFFSET0x208

#define CLK_SRC3_OFFSET0x20c

#define CLK_SRC4_OFFSET0x210

#define CLK_SRC5_OFFSET0x214

#define CLK_SRC6_OFFSET0x218

#define CLK_SRC_MASK0_OFFSET        0x280

#define CLK_SRC_MASK1_OFFSET        0x284


#define CLK_DIV0_OFFSET0x300

#define CLK_DIV1_OFFSET0x304

#define CLK_DIV2_OFFSET0x308

#define CLK_DIV3_OFFSET0x30c

#define CLK_DIV4_OFFSET0x310

#define CLK_DIV5_OFFSET0x314

#define CLK_DIV6_OFFSET0x318

#define CLK_DIV7_OFFSET0x31c


#define APLL_MDIV       0x7d// 125

#define APLL_PDIV       0x3

#define APLL_SDIV       0x1


#define MPLL_MDIV0x29b// 667

#define MPLL_PDIV0xc

#define MPLL_SDIV0x1


#define set_pll(mdiv, pdiv, sdiv)(1<<31 | mdiv<<16 | pdiv<<8 | sdiv)

#define APLL_VALset_pll(APLL_MDIV,APLL_PDIV,APLL_SDIV)

#define MPLL_VALset_pll(MPLL_MDIV,MPLL_PDIV,MPLL_SDIV)


.global clock_init

clock_init:

ldrr0, =ELFIN_CLOCK_POWER_BASE


// 設置CLK_SRC0寄存器bit[0]選FINPLL

ldrr1, =0x0

strr1, [r0, #CLK_SRC0_OFFSET]


// 設置PLL後,時鐘從輸入源FIN提升到目標頻率時,需要一定的時間。

ldrr1,=0x00000FFF

strr1,[r0, #APLL_LOCK_OFFSET]

str r1, [r0, #MPLL_LOCK_OFFSET]


// 設置APLL_CON0寄存器,FOUT = MDIV*FIN/(PDIV*2^(SDIV-1))=0x7d*24/(0x3*2^(1-1))=1000 MHz

ldrr1, =APLL_VAL

strr1, [r0, #APLL_CON0_OFFSET]

// 設置MPLL_CON0寄存器,FOUT = MDIV*FIN/(PDIV*2^SDIV)=0x29b*24/(0xc*2^1)= 667 MHz

ldrr1, =MPLL_VAL

strr1, [r0, #MPLL_CON_OFFSET]

// 設置CLK_DIV0寄存器清bit[0~31]。

ldr r1, [r0, #CLK_DIV0_OFFSET]

ldrr2, =0xFFFFFFFF

bicr1, r1, r2

// 設置CLK_DIV0寄存器[0~31]寫相關位。

ldrr2, =((0<<0) | (4<<4) | (4<<8) | (1<<12) | (3<<16) | (1<<20) | (4<<24) | (1<<28))

orrr1, r1, r2

strr1, [r0, #CLK_DIV0_OFFSET]


// 設置CLK_SRC0寄存器。

ldrr1, [r0, #CLK_SRC0_OFFSET]

ldrr2, =((1<<0) | (1<<4) | (1<<8) | (1<<12) | (0<<16) | (0<<20) | (0<<24) | (1<<28))

orrr1, r1, r2

strr1, [r0, #CLK_SRC0_OFFSET]


movpc, lr


參考資料:《ARM裸機全集---朱有鵬老師》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章