« XBeeをAPIモードで使う | トップページ | LPCXpresso LPC1769でCoreMarkを動かす »

LPCXpresso LPC1769の120MHzクロック設定

久しぶりの更新になってしまいました。簡単なネタですが、LPCXpresso LPC1769のクロック設定ついて記載します。

LPCXpresso LPC1769はその名のとおり、LPC1769を搭載しており120MHzのクロックをサポートしています。ただ、LPCXpresso IDE標準添付のCMSISライブラリを使用すると100MHzで動作します(初期のLPC1768時代の名残でしょうか)。せっかくのLPC1769(高クロック版)なので、持てる能力を引き出すために120MHzクロック動作への変更を行ってみました。

結論としては、CMSISライブラリフォルダーにあるsystem_LPC17xx.cのPLL0CFG_Valを変更することによってクロック周波数を変更できるのですが、その原理についても簡単に記載します。


LPC17xxのクロック設定

LPC17xxには、クロック設定に関連するレジスタとして以下があります:

  • PLL0CFG bit14-0:  MSEL0(PLL0 Multiplier value) → この値+1をMとする
  • PLL0CFG bit23-16:NSEL0 (PLL0 Pre-Divider value) → この値+1をNとする
  • CCLKCFG bit7-0: CCLKSEL(CPUクロックの分周比)→ 3(4分周)を設定

最初の2パラメータから以下の通り、PLLの周波数が決まります
PLL0の周波数  FCCO = (2 x M x Fin) / N  → Finは外部クロックの12MHz

CPUクロックはFCCO / (CCLKSEL+1)となるため、120MHz動作とするためには、FCCO = 480Mとなるように設定する必要があります。一方IDE添付のCMSISでは、system_LPC17xx.cのクロック関連設定が以下のように定義されています。

/*--------------------- Clock Configuration ----------------------------------
#define CLOCK_SETUP           1
#define SCS_Val               0x00000020	// The main oscillator is enabled
#define CLKSRCSEL_Val         0x00000001
#define PLL0_SETUP            1
#define PLL0CFG_Val           0x00050063	// MSEL = 99,  NSEL = 5 for 100MHz
#define PLL1_SETUP            1
#define PLL1CFG_Val           0x00000023
#define CCLKCFG_Val           0x00000003
#define USBCLKCFG_Val         0x00000000
#define PCLKSEL0_Val          0x00000000
#define PCLKSEL1_Val          0x00000000
#define PCONP_Val             0x042887DE
#define CLKOUTCFG_Val         0x00000000

PLL0CFG_ValがPLL0CFGレジスタに設定される値で、M = 100, N = 6が設定されており、
FCCO = (2 x 100 x 12M) / 6 = 400Mとなり、CPUクロックはその1/4である100MHzになります。

120MHzのクロックで動かすためには、Mを120に上げます。すなわち、PLL0CFG_Valを以下のように変更します。

#define CLOCK_SETUP           1
#define SCS_Val               0x00000020	// The main oscillator is enabled
#define CLKSRCSEL_Val         0x00000001
#define PLL0_SETUP            1
//#define PLL0CFG_Val           0x00050063	// MSEL = 99,  NSEL = 5 for 100MHz
#define PLL0CFG_Val           0x00050077	// MSEL = 119, NSEL = 5 for 120MHz
#define PLL1_SETUP            1
#define PLL1CFG_Val           0x00000023
#define CCLKCFG_Val           0x00000003
#define USBCLKCFG_Val         0x00000000
#define PCLKSEL0_Val          0x00000000
#define PCLKSEL1_Val          0x00000000
#define PCONP_Val             0x042887DE
#define CLKOUTCFG_Val         0x00000000

LPCXpresso IDEの環境では、CMSISはプリコンパイルしたライブラリとしてリンクするため、クロック設定を変えるとライブラリをビルドし直す必要があります。100MHzと120MHzの両方を使い分ける場合は、CMSISライブラリを2セット作る必要があると思います。


動作確認

以下のサンプルプログラムで100MHzと120MHzの処理速度を比較しました。

  • 37行目:SystemCoreClockUpdate()関数呼び出しでPLL0CFG/CCLKCFGレジスタを読み出し、CPUクロック値を計算して、SystemCoreClock(グローバル変数)に設定します
  • 38行目:SystemCoreClockをprintfでIDEのコンソールに出力 → printfをIDEに表示できるのは便利
  • 41行目:1ms周期のSysTick割り込みを設定
  • 48行目:ダミーの計算を実施
  • 52行目:計算時間を表示
/*
===============================================================================
 Name        : main.c
 Author      : todotani
 Version     : 1.0
 Copyright   : Copyright (C) 
 Description : main definition
===============================================================================
*/

#ifdef __USE_CMSIS
#include "LPC17xx.h"
#endif

#include <cr_section_macros.h>
#include <NXP/crp.h>
#include <stdio.h>

// Variable to store CRP value in. Will be placed automatically
// by the linker when "Enable Code Read Protect" selected.
// See crp.h header for more information
__CRP const unsigned int CRP_WORD = CRP_NO_CRP ;

#define LOOP 1000000
volatile uint32_t msTicks; // counter for 1ms SysTicks

//  SysTick_Handler
void SysTick_Handler(void) {
    msTicks++;
}


int main(void) {
    uint32_t dummy;
    uint32_t startTime, endTime;

    SystemCoreClockUpdate();
    printf("CPU Clock:%dMHz\n", SystemCoreClock/1000000);
	
    // Setup SysTick Timer to interrupt at 1 msec intervals
    if (SysTick_Config(SystemCoreClock / 1000)) {
        while (1);  // Capture error
    }

    uint32_t i;
    double a = 0;
    startTime = msTicks;
    for (i = 0; i < LOOP; i++) {
        a += ((double)i * 3.14);
    }
    endTime = msTicks;
    printf("Execution Time:%dms\n", endTime);

    while(1) {
        // 無限ループ
        dummy++;
    }

    return 0 ;
}

100MHzと120MHz動作で同じコードを走らせると(Debugビルドで比較)、以下のようにちょうど1.2倍性能が向上しました。めでたし、めでたし。

CPU Clock:100MHz
Execution Time:3399ms

CPU Clock:120MHz
Execution Time:2832ms

その他

LPCXpressoはトラ技別冊のMARY基板のデバック用にLPCリンクが使えないかと思って購入したのですが、MARY基板より先にこっちで遊んでしまいました。写真のLPCXpressoの真ん中にジャンパーポストがささっているのは、LPC Link基板部分を分離してデバッカーとして使う構想のために、CuBeatSystemsさんの「LPCXpressoを切り離さないで賢く使う方法」を拝借させていただきました。

LPCXpresso_001

« XBeeをAPIモードで使う | トップページ | LPCXpresso LPC1769でCoreMarkを動かす »

NXP-ARM」カテゴリの記事

コメント

この記事へのコメントは終了しました。

2018年10月
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
無料ブログはココログ