一、簡介
RT1010 有兩種外部Clock Source 和一個內部 Clock Source:
- High frequency oscillator ( 24MHz )
- Real time clock oscillator ( 32.768KHz )
- Internal ring oscillator ( 1MHz )
本文將介紹如何配置系統 Clock,具體上的 Register 內有哪些設定、是如何設定的;再透過 evkmimxrt1010_ccm_clockout 範例程式實際為 Clockout 配置各種頻率,包含如何從不同的 Source 獲得頻率、自身進行不同倍率的除頻。
二、Clock 的規格
外部OSC ( 振盪器 ) 介紹:
兩端所接電容 ( 24MHz 的 C36 & C37、RTC 的 C44 & C45 )
並聯起來的電容值約等於負載電容
若負載電容值增大,則晶體振盪頻率降低、振盪穩定度增加、起振時間延後
並聯一個電阻 ( R30 ) 可穩定波形和使振盪器容易起振
下圖為 24M OSC ( XRCGB24M000F2P29R0 ) 的規格,
如圖所示 Load Capacitance 為 8pF
各個 Clock 在不同功耗模式下的頻率上限,建議各個模式下設定 Clock 頻率的時候不要超出上表的最高頻率。
OSC ( 24MHz ) 提供頻率給各個 PLL ( Phase-locked loops ) 進行倍頻,PLL2、PLL3 再經過各自的 PFD ( Phase Fractional Dividers ) 倍頻或除頻出各種頻率,最終產生接近各個周邊所需要的頻率 ( Clock )。
- PLL2 在 RT1010 又可被稱為 System PLL
- PLL3 在 RT1010 又可被稱為 USB1 PLL
- PLL4 在 RT1010 又可被稱為 Audio PLL
- PLL6 在 RT1010 又可被稱為 ENET PLL
*詳見 i.MX RT1010 Processor Reference Manual , REV. 0 的 14.6.1 章節
三、System Clock 相關的 Register 說明
下圖為 RT1010 的 Clock Tree,CLOCK SWITCHER 選擇 PLL 和 PFD,然後各個周邊通過 Mux select 選擇需要的 Clock Source,最後通過除頻變成 SYSTEM CLOCKS 所需的頻率,本章節以 ARM Core Clock 為例說明相關的 Register 內容。
下圖為系統 ARM core Clocks 的 Block diagram:
以下是方塊圖中所有可能用到的 Register 的說明:
1). CCM_ANALOG_PLL_SYSn [ BYPASS_CLK_SRC ]
選擇 24MHz OSC 為 source
2). CCM_ANALOG_PLL_SYSn [ DIV_SELECT ]
設成 1 讓 PLL 倍頻為 22 倍 ( 若設為 0 則為 20 倍 )
3). CCM_ANALOG_PFD_528n [ PFD3_FRAC ]
設定 PFD 的倍頻和除頻
4). CCM_ANALOG_PLL_SYSn [ BYPASS ]
選擇是否要經過 PLL 倍頻
5). CCM_ANALOG_PFD_480n [ PFD3_CLKGATE ]
選擇是否要經過 PFD 倍頻
6). CCM_ANALOG_PLL_USB1n [ BYPASS ]
選擇 24MHz OSC 為 source
7). CCM_ANALOG_PLL_USB1n [ DIV_SELECT ]
設成 0 讓 PLL 倍頻為 20 倍 ( 若設為 1 則為 22 倍 )
8). CCM_ANALOG_PFD_480n [ PFD3_FRAC ]
設定 PFD 的倍頻和除頻
9). CCM_ANALOG_PLL_USB1n [ BYPASS ]
選擇是否要經過 PLL 倍頻
10). CCM_ANALOG_PFD_480n [ PFD3_CLKGATE ]
選擇是否要經過 PFD 倍頻
11). CCM_CCSR [ PLL3_SW_CLK_SEL ]
選擇 PLL3_SW_CLK_SEL 的 source 來源
12). CCM_ANALOG_PLL_ENETn [ BYPASS_CLK_SRC ]
選擇 24MHz OSC 為 source
13). CCM_ANALOG_PLL_ENETn [ ENET_500M_REF_EN ]
允許 PLL 將 source 倍頻成 500MHz
14). CCM_ANALOG_PLL_ENETn [ BYPASS ]
選擇是否要經過 PLL 倍頻
15). CCM_CBCMR [ PRE_PERIPH_CLK_SEL ]
選擇 PRE_PERIPH_CLK_SEL 的 source 來源
16). CCM_CBCMR [ PERIPH_CLK2_SEL ]
選擇 PERIPH_CLK2_SEL 的 source 來源
17). CCM_CBCMR [ PERIPH_CLK_SEL ]
選擇 PERCLK_CLK_SEL 的 source 來源
18). CCM_CBCDR [ AHB_PODF ]
選擇 AHB_PODF 的除頻值
依據 Register 的說明在對應的位置填入對應的值,即可根據需求設定 Register 的值,進而設出想要的頻率。
四、實作
直接以 Register 配置 Clockout1 的 Clock 為 ARM Core Clock,然後透過 Clockout Pin 輸出量測配置結果
紅色部分為具體配置路線
CLK01 (TP34) 、 CLK02 (TP31)
以下是兩根 Clockout Pin 可量測的 Source
CLKO1:
PLL3 SW Clock ( Divided by 2 )、PLL2 Clock ( Divided by 2 )、ENET PLL Clock ( Divided by 2 )、Core Clock Root、IPG Clock Root、Perclk Root、PLL4 Main Clock
CLKO2:
LPI2C Clock Root、OSC Clock、LPSPI Clock Root、SAI1 Clock Root、SAI3 Clock Root、Trace Clock Root、Flexspi Clock Root、UART Clock Root、Spdif0 Clock Root
固定為 Pin74 & Pin75 無法修改
完整程式碼:
XTALOSC24M->LOWPWR_CTRL = (( 0 << XTALOSC24M_LOWPWR_CTRL_OSC_SEL_SHIFT) & XTALOSC24M_LOWPWR_CTRL_OSC_SEL_MASK);
CCM_ANALOG->PLL_USB1 = (( 0 << CCM_ANALOG_PLL_USB1_BYPASS_CLK_SRC_SHIFT) & CCM_ANALOG_PLL_USB1_BYPASS_CLK_SRC_MASK);
CCM_ANALOG->PLL_USB1 = (( 0 << CCM_ANALOG_PLL_USB1_DIV_SELECT_SHIFT) & CCM_ANALOG_PLL_USB1_DIV_SELECT_MASK);
CCM_ANALOG->PLL_USB1 = (( 1 << CCM_ANALOG_PLL_USB1_BYPASS_SHIFT) & CCM_ANALOG_PLL_USB1_BYPASS_MASK);
CCM->CCSR = (( 0 << CCM_CCSR_PLL3_SW_CLK_SEL_SHIFT) & CCM_CCSR_PLL3_SW_CLK_SEL_MASK);
CCM->CBCMR = (( 0 << CCM_CBCMR_PERIPH_CLK2_SEL_SHIFT) & CCM_CBCMR_PERIPH_CLK2_SEL_MASK);
CCM->CBCDR = (( 1 << CCM_CBCDR_PERIPH_CLK_SEL_SHIFT) & CCM_CBCDR_PERIPH_CLK_SEL_MASK);
CCM->CBCDR = (( 0 << CCM_CBCDR_AHB_PODF_SHIFT) & CCM_CBCDR_AHB_PODF_MASK);
CCM->CCOSR = (( 1 << CCM_CCOSR_CLKO1_EN_SHIFT) & CCM_CCOSR_CLKO1_EN_MASK);
CCM->CCOSR = (( 7 << CCM_CCOSR_CLKO1_DIV_SHIFT) & CCM_CCOSR_CLKO1_DIV_MASK)
CCM->CCOSR = (( 11 << CCM_CCOSR_CLKO1_SEL_SHIFT) & CCM_CCOSR_CLKO1_SEL_MASK);
程式碼說明:
選擇 24MHz XTAL OSC 為 OSC 的 Source 來源
實際修改 Register 命令
XTALOSC24M->LOWPWR_CTRL = (( 0 <<XTALOSC24M_LOWPWR_CTRL_OSC_SEL_SHIFT) & XTALOSC24M_LOWPWR_CTRL_OSC_SEL_MASK);
選擇 24MHz OSC 當作 PLL3 的 Source
實際修改 Register 命令
CCM_ANALOG->PLL_USB1 = (( 0 << CCM_ANALOG_PLL_USB1_BYPASS_CLK_SRC_SHIFT) & CCM_ANALOG_PLL_USB1_BYPASS_CLK_SRC_MASK);
將 PLL3 的倍頻調整為 20 倍
實際修改 Register 命令
CCM_ANALOG->PLL_USB1 = (( 0 << CCM_ANALOG_PLL_USB1_DIV_SELECT_SHIFT) & CCM_ANALOG_PLL_USB1_DIV_SELECT_MASK);
選擇經過 PLL3 倍頻
實際修改 Register 命令
CCM_ANALOG->PLL_USB1 = (( 1 << CCM_ANALOG_PLL_USB1_BYPASS_SHIFT) & CCM_ANALOG_PLL_USB1_BYPASS_MASK);
選擇 pll3_main_clk ( 倍頻過的頻率 ) 為 PLL3_SW_CLK 的 Source
實際修改 Register 命令
CCM->CCSR = (( 0 << CCM_CCSR_PLL3_SW_CLK_SEL_SHIFT) & CCM_CCSR_PLL3_SW_CLK_SEL_MASK);
選擇 pll3_sw_clk 為 PERIPH_CLK2_SEL 的 Source
實際修改 Register 命令
CCM->CBCMR = (( 0 << CCM_CBCMR_PERIPH_CLK2_SEL_SHIFT) & CCM_CBCMR_PERIPH_CLK2_SEL_MASK);
選擇PERIPH_CLK2_SEL 為 PERIPH_CLK_SEL 的 Source
實際修改 Register 命令
CCM->CBCDR = (( 1 << CCM_CBCDR_PERIPH_CLK_SEL_SHIFT) & CCM_CBCDR_PERIPH_CLK_SEL_MASK);
選擇 AHB_PODF 的除頻值為 1
實際修改 Register 命令
CCM->CBCDR = (( 0 << CCM_CBCDR_AHB_PODF_SHIFT) & CCM_CBCDR_AHB_PODF_MASK);
Enable CLKO1、設定 CLKO1 的 source 和 divide 值
實際修改 Register 命令
CCM->CCOSR = (( 1 << CCM_CCOSR_CLKO1_EN_SHIFT) & CCM_CCOSR_CLKO1_EN_MASK);
CCM->CCOSR = (( 7 << CCM_CCOSR_CLKO1_DIV_SHIFT) & CCM_CCOSR_CLKO1_DIV_MASK)
CCM->CCOSR = (( 11 << CCM_CCOSR_CLKO1_SEL_SHIFT) & CCM_CCOSR_CLKO1_SEL_MASK);
實際運行的結果:
Source = Arm core clock = 480MHz,Divider = 8
理論輸出值為 60MHz,實際量測結果為 60.2MHz
五、附錄
- 一些常用的Register 全名:CCM (Clock Control Module)
CCM_CCR (CCM Control Register)
CCM_CSR (CCM Status Register)
CCM_CCSR (CCM Clock Switcher Register)
CCM_CBCDR (CCM Bus Clock Divider Register)
CCM_CBCMR (CCM Bus Clock Multiplexer Register)
參考資料:i.MX RT1010 Processor Reference Manual .pdf
評論