SNSへはこちら

簡単USBマイコン EZ-USB FX2LP(4) - 簡単にGPIFをやってみる 後半

前回の記事の後半です。ここでは、実際の GPIF 初期化コードを書いていきます。

初期化コード全体

いきなりですが、全体です。前回の配列は省略しています。

void GpifInit(void) {
    IFCONFIG = 0xC2;
    GPIFABORT = 0xFF;  // abort any waveforms pending & go into idle state

    GPIFREADYCFG = 0x20; // connect RDY siglal to GPIF
    GPIFCTLCFG = 0x00; // All CMOS output, Output Enabled
    GPIFIDLECS = 0x00; // Data bus is not driven during idle state.
    GPIFIDLECTL = 0x00; // Disable All output during idle state
    GPIFWFSELECT = 0x00; // tekitou(wave form 0 is chosen in all xfer/recv modes)

    volatile char *dest = &GPIF_WAVE_DATA;
    const char *src = (const void *)WaveData;
    for(unsigned int i = 0; i < 4 * 4 * 8; i++) {
        dest[i] = src[i];
    }
}

解説

それではざっくりと解説をしていきましょう。お手元にユーザーマニュアルをどうぞ。

GPIF設定の準備

    IFCONFIG = 0xC2;
    GPIFABORT = 0xFF;  // abort any waveforms pending & go into idle state

ここでは GPIF を設定する前の準備をしています。IFCONFIG の値は、1. IFCLK = 48MHz, 2. GPIF マスターモード、3. 非同期(Asynchronous)モードでの動作 を示しています。3. については、実際に SRAM 等でスレーブと通信をする時にクロックを使うことがあると思いますが、どうやらそういった時にマスタとスレーブをクロックで同期して動かしたい時に使うモードらしいです。また、3bit 目を1にすると、PORTE[2:0] がステート番号を表すようになるらしい。デバッグ用らしいです。

GPIFABORT0xFF を書き込むと、現在進行中の GPIF 動作を全て強制終了させて Idle State に移行させるものです。このレジスタには他の値を書き込んでも何も起きません。

GPIFのハードウェア設定

    GPIFREADYCFG = 0x20; // connect RDY siglal to GPIF
    GPIFCTLCFG = 0x00; // All CMOS output, Output Enabled
    GPIFIDLECS = 0x00; // Data bus is not driven during idle state.
    GPIFIDLECTL = 0x00; // Disable All output during idle state
    GPIFWFSELECT = 0x00; // tekitou(WaveData 0 is chosen in all xfer/recv modes)

ここで GPIF を使う上で一番最初の初期化をしています。データバスとの接続、出力ピンのモード選択、出力 WaveForm の選択です。起動時の GPIF アイドル時の設定があるんですね〜今回は関係ありませんが。
最後の GPIFWFSELECT では、とりあえず Single Write から FIFO Read まで全て WaveData0 を使う設定にしてあります。

WaveFormデータのコピー

    volatile char *dest = &GPIF_WAVE_DATA;
    const char *src = (const void *)WaveData;
    for(unsigned int i = 0; i < 4 * 4 * 8; i++) {
        dest[i] = src[i];
    }

これでデータをコピーしています。ここには前回の記事の OPCODE 等々のレジスタ値が記述されています。

これで設定は終わりです!ちなみに現状は Idle state に入っていて、しかも FLOWSTATE の値によると、初期値で 0 だそうです。つまり最初に動作を開始する時は S0 から始まるということです。
今回はこれで都合がいいので、他の設定はいじらずこれで OK!

動かしてみよう

GPIF の設定は完了しましたが、このあと Single Write 動作で、GPIF をトリガする必要があります。なので、早速 main 関数にて記述しましょう。

int main(void) {
    GpifInit();
    XGPIFSGLDATLX = 1;
    while(1) {
    }
}

XGPIFSGLDATLX = 1 がまさに Single Write を行うところです。今回はこの 1 という値に意味はありません。好きな値にどうぞ。とにかく、Single Write が行われたということ自体が重要なのです(この動作自体が設定した GPIF の動作をトリガするので)。

後は GPIF が勝手に状態遷移を無限ループしてくれるので、ソフトウェアでは何もすることがありません。実際、RDY0 & RDY1 == 1 のときにのみ CTL0 の出力は 1 になりました!