作成日:2013-3-29

LPCXpresso LPC1347 または LPC1315-LPC1347 を使う
その2 〜LPC1343のプロジェクトをLPC1347プロジェクトにポーティング〜

LPCXpresso LPC1343のプロジェクトを LPCXPresso LPC1347へポーティングする

LPCXpressoのノート10で LPC1311-LPC1343 と LPC1345-LPC1347 の違いについて書きました。
ここではLPC1343のプロジェクトをLPC1347にポーティングしてみます。
LPCXpresso IDEをインストールすると(インストールに関してはこちらを参照)、インストールしたフォルダ内のExsampleフォルダにサンプルプロジェクトがあります(こちらを参照)。 LPC1347のサンプルプロジェクトは \\Examples\NXP\LPC1000\LPC13xx_12bitADC 内にあります。LPC1311-LPC1343のサンプルプロジェクトは「LPC13xx」ファルダです。区別するのにファルダ名が「LPC13xx_12bitADC」になっています。
残念ながら、LPC1315-LPC1347のサンプルは、LPC1311-LPC1343と異なるUSBのサンプルとsystickのみです(SystickはARMコア内のタイマのことで、LEDチカチカサンプル)。
LPCXpresso LPC1347のサンプルライブラリは新しいソフトウェアLPCOPenプラットフォームにもあります。LPCOpenはデバイス間のIPの違いを吸収する様になっています、 詳しくはこちらをご覧ください。

    1. インポートするファイルは上記フォルダ内の「LPCXpresso1347.zip」、インポートした図は図1。使うプロジェクトは"LPCXpresso1347_systick"。
    2. 一方、LPC1343のサンプルは「examples.lpc13xx.new.zip」を使う、インポートした図2は。LPCXPresso IDEは複数同時に起動可能。
    3. インポートした「examples.lpc13xx.new.zip」の"blinky"プロジェクト(これもLチカサンプル)をLPCXPresso LPC1347の"LPCXpresso1347_systick"にポーティングする。
      LPCXpressoのノート10の様に、LPC1347とLPC1343はGPIOが違います。ですので、GPIOはLPC1347のもを使います。それ以外のファイル
      • blinky_main.c
      • clkconfig.c
      • clkconfig.h
      • config.h
      • timer32.c
      • timer32.h
      をLPC1347の"LPCXpresso1347_systick"プロジェクトにコピー。 "LPCXpresso1347_systick"プロジェクト内のmain関数のある"systick.c"は削除。図3。


    4. 次にヘッダーファイル名をLPC1315-LPC1347用に変更、ファイル名は"LPC13Uxx.h"、このファイルは「CMSISv2p10_LPC13Uxx」の中にある (LPC1311-LPC1343のヘッダーファイル名は"LPC13xx.h")。
      検索で"LPC13xx.h"を見つけ、"LPC13Uxx.h"変更する(「Cnrl + H」で検索できます、図4。検索結果は図5。)。変更後、ビルド。

    5. エラーがでました。エラーが出た関数 "WDT_CLK_Setup" と "CLKOUT_Setup" が使われているかどうか検索してみる。どちらも使われていないので、"clkconfig.c" と "clkconfig.h" をプロジェクトから削除。
    6. ビルド。消した"clkconfig.h"ファイルがないと言われるので"#include "clkconfig.h"をコメントアウト。
    7. ビルド。"LPC_TMR32B0" と "LPC_TMR32B1” の名前が定義されていないと言われる。"LPC13xx.h" と "LPC13Uxx.h" を見比べるとタイマーの名前の定義が "LPC_TMR"(LPC13xx.h 図8)から "LPC_CT"(LPC13Uxx.h 図9) に変わっている。 「Ctrl + H」で 「Containing_text」(「File Search」タブ内) に "LPC_TMR" を入れ、「Relpace」ボタンを押す(図10)。変更する文字として"LPC_CT"を入れ、「Preview>」ボタンを押すと置換される一覧が出てくるので「OK」(図11)。

    8. ビルド。割り込み名が定義されていないとエラー(図12)。"LPC13Uxx.h"を確認、これも名前が変更されているので "TIMER_32_0_IRQn" を "CT32B0_IRQn" へ "TIMER_32_1_IRQn" を "CT32B1_IRQn"へ変更(図13)。
    9. ビルド。今度は "GPIOSetValue" という関数が定義されていないとうエラー(図14)。オリジナルのLPC1343のプロジェクトでその関数を探すと、"gpio.h"内で定義している。 "LPCXpresso1347_systick"プロジェクトの"gpio.h"を見ると"GPIOSetBitValue"と異なる名前。"gpio.c"内も確認する、これだ! "GPIOSetBitValue"に書き換える。


    10. ビルド。CRP(Code Read Protection)に関する記載がないと言う。"blinky_main.c" は、CMSISv1p30用のファイルなのでポーティング先の CMSISv2p10 の書き方にする必要がある。 「LPCXpresso1347.zip」をインポートした時に一緒にインポートされた "LPCXpresso1347_systick_twinkle"プロジェクトのmain関数のある"systick.c"を見ると、図15の様になっている。 "blinky_main.c"も同じに様にする(図16)。
    11.                 
      #ifdef __USE_CMSIS
      #include "LPC13Uxx.h"
      #endif
       
      #include <cr_section_macros.h>
      #include <NXP/crp.h>
       
      #include "gpio.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 ;
      
      図15
                         
      #ifdef __USE_CMSIS
      #include "LPC13Uxx.h"                        /* LPC13xx definitions */
      #endif
       
      #include <cr_section_macros.h>
      #include <NXP/crp.h>
       
      //#include "clkconfig.h"
      #include "gpio.h"
      #include "config.h"
       
      #include "timer32.h"
       
      __CRP const unsigned int CRP_WORD = CRP_NO_CRP ;
      
      図16
    12. ビルド。やっとビルド通りましたね。LPCXpresso LPC1347にプログラムを「Debug」でダウンロードしてRunします。
      LED2が光りません。デバッグを止めると、「IntDefaultHandler」内で止まっています。コードに説明がありますが、予期しない割り込み もしくは 割り込むハンドラーがない時にここに飛んできます。
      このプログラムはタイマーの割り込みで時間をカウントとしてLEDを点滅させるプログラムなっています。"timer32.c"タイマーの割り込みのところを見てみます。タイマーの割り込みハンドラーの名前が「TIMER32_0_IRQHandler」になっています。 この名前が正しいか確認します。各割り込み名前はスタートアップファイル"cr_startup_lpc13.c"の中であらかじめ定義されています。32-bit Timer0 の名前は「CT32B0_IRQHandler」と定義さてています(図17)、これが原因ですね! 名前を変更して(図18)ビルド、「Debug」でプログラムをダウンロードしてRunさせます。LEDが点滅しました。これでポーティング完了です!
    13. void CT32B0_IRQHandler(void)
      {  
        LPC_CT32B0->IR = 1;			/* clear interrupt flag */
        timer32_0_counter++;
        return;
      }
      
      図18
作成日:2013-3-29