So-net無料ブログ作成
検索選択

ColdFire V1 のバス周波数を目で確認する [ColdFire (ColdeFire) V1]このエントリーを含むはてなブックマーク#

命令実行時間を測定するために、アセンブラでソフトウェア・ループを組み、 LEDを点滅させてみました。

#include  /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */

プログラムは、全部main関数に押し込んであります。

void main(void) {
犬のおまわりさん(COP)を黙らせるためには、HCS08同様にSOPT1レジスタを設定します。 このあたりの勝手は、HCS08と同じなので、今までの経験が役立ちます。
  SOPT1
  = 0b01010111;
//    |||| ||+--- RSTPE=1  Enable RST port
//    |||| |+---- BKGDPE=1 Enable BKGD port  
//    |||| +----- RSTOPE=1 Enable RSTO port
//    |||+------- WAITE=1  Enable WAIT
//    ||+-------- STOPE=0  Disable STOP
//    |+--------- COPT=1   Disable COP
//    +---------- COPE=0   Disable COP
バスクロック周波数を設定する方法もHCS08同様です。 QE128は、DRSというレジスタが追加されて、Digitally Controlled Oscillator (DCO)の 出力周波数倍率が変更できるようになっています。 ここでは、 内部参照クロックを31.25kHzに設定し、 DCO出力を内部参照クロックの1536倍、すなわち48MHzに設定します。 バス・クロック周波数は、その半分の24MHzになるはずです。
  // Configure ICS
  ICSC2_BDIV      = 0;  // BDIV 1/1
  ICSSC_DRST_DRS  = 2;  // FLL x1536

LEDを点灯させるために、RGPIOという新モジュールを使います。 ここで使用するポートは、RGPIO8(PTC0)のみです。 RGPIOを出力としてイネーブルします。

  // Configure RGPIO8=PTC0 as output
  RGPIO_DIR_DIR8 = 1;
  RGPIO_ENB_ENB8 = 1;
処理本体では、時間稼ぎループをアセンブラで記述しています。 ループ回数は、4,000,000回です。 MCF51QE128のリファレンス・マニュアルによれば、ループ一回で3バス・クロック要するので、 時間稼ぎ部分で12,000,000バスサイクルを消費するはずです。 バス周波数を24MHzに設定すると、0.5秒に相当します。 nopについては、のちほど。
  
  for(;;) {
    __asm {
      move.l  #4000000,d0
//      nop
      L1:
      subq    #1,d0        //  1(0/0)
      bne     L1           //  2(0/0) backward taken
    }
時間稼ぎが終わったら、RGPIOの出力を反転させます。 0.5秒毎に反転されるので、1秒周期でLEDが点滅します。
    // Toggle RGPIO10
    RGPIO_TOG = RGPIO_TOG_TOG8_MASK;
  } /* loop forever */
  /* please make sure that you never leave main */
}

これで、1秒周期でLEDが点滅するはずです。 ところが、実際の点滅周期は、2/3秒になってしまいました。 なぜなんだろう。

ループの回数を間違えることはないと思われるので、 ループ当たりのバス・サイクル数が2サイクルになったと推測しました。

色々とやり直した結果、ラベル"L1"のアドレスが、"0-modulo-4"だった場合は、 ループ当たり2バス・サイクルを消費し、 "2-modulo-4"の場合は、3サイクルを消費するらしいことがわかりました。 nopをコメントからはずすと、結果が異なってきます。 えっ?リファレンス・マニュアルが違うの?それとも、シリコン?

まさに、パイプラインのなせる業。 インライン・アセンブラは、".align 4"を入れることが出来ないらしいので、 こういった使い方をする際には、要注意です。

RGPIOを使った理由

RGPIOというのは、簡単に16本のポートの操作を行うありがたい仕掛けなのですが、 これを使ったのには理由があります。 この解に至るまでにHCS08で良く使われる以下のような構文を試してみました。

  • PTCD_PTCD0 = !PTCD_PTCD0;
  • PTCD_PTCD0 = ~PTCD_PTCD0;
  • PTCD ^= PTCD_PTCD0_MASK;

ところが、こいつらが見るに耐えない冗長なコードを出力してしまったので、 RGPIOの登場となったしだいです。 どんな、冗長なコードができたかは、ぜひ、ご自身でお試しください。


nice!(0)  コメント(1)  トラックバック(0)  このエントリーを含むはてなブックマーク#

nice! 0

コメント 1

hamayan

> 犬のおまわりさん(COP)を黙らせるためには、HCS08同様に
> SOPT1レジスタを設定します。このあたりの勝手は、HCS08と
> 同じなので、今までの経験が役立ちます。

TPMもHCS08の経験がそのまま、と言うか処理そのものを流用できるので、HCS08からの移行組みは楽できますね。

うん、コントローラコンティナムだ!。
by hamayan (2008-01-18 06:59) 

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

トラックバックの受付は締め切りました

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。