7/22/2011

Cortex-M0ボード:ハードの基礎・マニュアルの読み方





学生へのチュートリアルと備忘録を兼ねてメモしておきます.

Cortex-M0ボードに搭載・接続されている様々なハードウェアを使用するためのやり方は,先に紹介したトラ技2011年4月増刊や本誌連載(2〜8月号)にわかりやすく解説されています.しかし,ちょっと自分で何かやろうとするとすぐにこれでは情報が足りないことに気づくでしょう.著者自身も書いているように,ちゃんと理解するにはデータシートやマニュアル,そしてソースファイルを読むことが何よりも近道です.

【例】
  • ポートPIO_1_8 (汎用IOポート1の8番端子)からON/OFF信号を出力したいとします.増刊号のp.50, あるいは配布ファイルCQ.zipの LPC1114/hardware/LPC1114_MARY_DesignData.pdf を参照すると,PIO1_8はMARYボードのCN3の1番ピンに割り当てられていることがわかります.また表Aの右の方を見ると,OB, LB, XB, GB, UB などの拡張ボードではすでに別の用途に使用されているので,PIO1_8を使うときはこれらのボードを外さなければならないこともわかります. この端子からON信号を出力するには以下のようにします.
    #Ifdef __USE_CMSIS
    #include "LPC11xx.h"
    #endif
    
    #include "gpio.h"
    
    int main(void)
    {
        GPIOSetDir(1, 8, 1);   // PIO1_8 : OUTPUT
        GPIOSetValue(1, 8, 1);   // ON
        while(1) {}
        return 0; 
    }
    

    最初の3行は,まずはオマジナイだと思って下さい.汎用入出力のための関数のヘッダファイルが gpio.h で,この中で GPIOSetDir や GPIOSetValue が宣言されています.GPIOSetDir で信号の入出力方向を「出力」に設定し,GPIOSetValueで ON や OFF の値をセットするわけです.

  • 次に,同じことをポートPIO_1_0についてやろうとしてみます.PIO_1_0はMARYボードのCN4の6番ピンです.GPIOSet...
    の部分を
        GPIOSetDir(1, 0, 1);   // PIO1_0 : OUTPUT
        GPIOSetValue(1, 0, 1);   // ON
    
    と変えれば十分のように思いますが,これだけではうまくいきません.

    その理由は,p.50表Bの「端子番号7」と「22」のところを比べてみるとわかります.ここでいう端子番号とはMARYボードのピン番号とは別で,ボード上にみえる8mm角ほどのマイコンチップ本体,LPC1114の端子番号の事です.このLPC1114のような小型のマイコンチップでは,サイズを節約するために一つのピンに複数を機能を割り当てていることが多いのです.端子7はPIO1_8/CT16B1_CAP0の2種類兼用,端子22はPIO1_0/TMS/CT32B1_CAP0/AD1の4種類兼用というように.端子を使うときには,このうちどの役割をさせるのかを指定しないといけないわけです.表Bの2列目をみると端子機能のデフォルト設定が書いてありますね.端子7はデフォルト(リセット直後)でPIO1_8になっているのでたまたま設定の必要がなかったのですが,端子22はReservedとなっているので明示的に設定しないといけないわけです.

    端子22をPIO1_0として機能させるためには,上記2行の前に
        LPC_IOCON->R_PIO1_0   = 0xd1; // PIO1_0 -> PIO1_0
    の一行を追加する必要があります.

【マニュアルの読み方】
こういった情報はどこを調べればよいのでしょうか.そのためにはまず,このMARYボードシステムの基本的な成り立ちを理解する必要があります.

名称開発元マニュアル
1. CPUコアCortex-M0ARMCortex-M0テクニカルリファレンスマニュアル (ARM DDI0432CJ)
2. マイコンチップ(MCU)LPC1114NXPセミコンダクタLPC111x/LPC11C1xユーザーマニュアル (NXP UM10398)
3. マイコンボードMARYCQ出版・圓山宗智氏トラ技増刊号,CQ.zip に附属のドキュメント他
包含関係はCortex-M0 ⊂ LPC1114 ⊂ MARY です(※).いわゆるCPUはCortex-M0ですが,これは表には見えていません.見えているのはLPC1114で,これはCortex-M0をコアとしてタイマやA/Dコンバータといった周辺機能を1チップにまとめたものです.MARYボードはCQ出版・圓山氏が今回の企画で開発したもので,LPC1114を中心に電源,USBインタフェース,コネクタ・スイッチ・LEDなどがついて完成したシステムになっています.

なにか調べようとしたとき,それが3つのうちどれに関係しているのか,を考えれば参照すべきマニュアルがわかるでしょう.基本的な演算能力や命令セットについて知りたければCortex-M0のマニュアル(1)を見ます.タイマ,I/Oポート,A/D変換,UART(シリアル入出力) などの周辺機能関連についてはすべて LPC1114の マニュアル(2)を見ることになりますので,おそらく最も参照頻度が高いと思われます.LPC1114のある端子がどのコネクタに出ているかとか,電源関係,拡張ボードの使い方などに関することはすべて MARY のマターになります.さらにはライブラリ,ヘッダファイル,サンプルプログラムなどのソフトウェアもCQ出版・圓山氏の作によるものなので,トラ技の記事やCQ.zipに附属ドキュメント(3)に頼ることになります.

さて,上の例の場合は汎用入出力GPIOの設定の問題ですので,LPC111xユーザーズマニュアルを開きます.第6章のTable 80を見ますと,PIO1_0端子の機能を設定するレジスタ IOCON_R_PIO1_0 の設定方法の説明が出ています.端子機能を PIO1_0 にセットするには第2〜0ビットを 001 にします.その他の第7〜3ビットはデフォルトのままで 11010 としますので,あわせて 11010001B = 0xd1 をセットすればよいというわけです.

※当然ですが,Cortex-M0を使ったマイコンチップはLPC1114以外にもありますし,LPC1114を使ったボードも MARY以外にもたくさんあります.また,Cortex-M0の命令セットはThumbといって,他のいくつかのCPUにも共通して使われています.


【追記:C言語からのアクセス】
LPC1114のユーザーマニュアルを見て周辺機能レジスタの詳細を理解したとして,実際にそれにどうやってアクセスするかを確認するには LPC1114/workspace/CMSISv1p30_LPC11xx/inc/LPC11xx.h を参照するとわかりやすいです.例えば上述したIOCON_R_PIO1_0にアクセスしたいと思ったら,LPC11xx.hの中を検索すると
/*------------- Pin Connect Block (IOCON) --------------------------------*/
/** @addtogroup LPC11xx_IOCON LPC11xx I/O Configuration Block 
  @{
*/
typedef struct
{

 ...(中略)...

  __IO uint32_t R_PIO1_0;               /*!< Offset: 0x078 I/O configuration for pin TMS/PIO1_0/AD1/CT32B1_CAP0 (R/W) */

 ...(中略)...

} LPC_IOCON_TypeDef;
/*@}*/ /* end of group LPC11xx_IOCON */
という構造体の定義部分が見つかります.さらにLPC_IOCON_TypeDefで検索すれば,その下の方に
#define LPC_IOCON             ((LPC_IOCON_TypeDef  *) LPC_IOCON_BASE )
とあって,構造体の実体がLPC_IOCONという名前で宣言されていることがわかります.それで,LPC_IOCON->R_PIO1_0と記述すれば構造体のメンバR_PIO1_0を読み書きできるというわけです.

※冒頭に書いたオマジナイは,このLPC11xx.hをインクルードするためのものです.