· 

SPIハードをFPGAで(5)

Eclipseを起動する。

これで、プロジェクトの下にsoftwareってフォルダができて、それがワークスペースになる。

起動を待つ。eclipseは相変わらず遅い。

出てきたeclipseの開発環境のProject Explorerの白い部分を右クリックして、ポップアップメニューでNew-->Nios II Application and BSP from Templeteを押す。

SOPC(System-on-a-Programmable-Chip) information fileってのを指定する。

 

Platform Designerで自動的に作られているからそれを選択する。

ちょっと時間を要した後に、CPU nameのところにPlatformDesignerで作ったNiosIIコアの名前が入っている。ProjectNameをPROGとして、Hello Worldテンプレートを選んでNextを押す。

いじらずにFinishを押す。

プログレスダイアドルが表示されたり消えたりをして、最終的にはProject ExplorerにPROGとPROG_bspができる。

PROGのツリーを開いて、hello_world.cを右クリックしてRename...をクリック。

main.cってことにしてOKを押す。

PROG_bspを右クリックして、NiosII-->BSP Editor...と押す。

でてきた画面でこうする。exception_stack_memory_region_nameとか、interrupt_stack_memory_region_nameとか、今回はSRAMしかないから選択肢がないけど、FPGAにSDRAMをつなぐとSDRAMも選べる。

これも今回は関係ないけど、Linker Scriptタブを見る。

今のところこれでいいけど、SDRAMをつなぐとSDRAMも選べる。

まぁ今回は触らずにCtrl+Sを押して、Generateを押して、Exitを押す。

PROGをクリックしてアクティブにした状態で、Project-->Clean...を押す。

OKを押す。

何となく終わった雰囲気になる。

#include 

int main()
{
  printf("Hello from Nios II!\n");

  return 0;
}

Hello World テンプレートを使ったので、現在のmain.cはこうなっている。いったんこれを実行してみる。

PROGプロジェクトを選んだ状態で、Run-->Debug Configurations...

NiosII Hardwareを押してから左上のnewアイコンを押す。

実行可能なプロジェクトを選んだ状態でDebugConfigurationsを開始したので、Projectの情報はすでに入れてくれている。Nameを適当に変えて、Target Connectionタブを押す。

Refresh Connectionsを押してからSystem ID Properties...を押す。

FPGAのSystemIDとの照合が行われて、現在のeclipseのプロジェクトのターゲットが実際のFPGAに書き込まれているNiosIIコアであることを確認したんだと思う。Closeを押す。

Applyが押せる状態ならApplyを押し、Debugを押す。

eclipseの見た目をデバッグ風にするかどうかってことで、Yesを押す。

main入ってすぐのところで止まるので、ステップ実行する。

下の、Nios II Consoleにプログラムで指示した通りの表示が出る。JTAG UARTがちゃんと動いているってことでしょう。

とめる。

eclipseの見た目を元に戻す。

#include <stdio.h>
#include <stdint.h>
#include "system.h"
#include "altera_avalon_pio_regs.h"

uint8_t MYSPI_CONFS[]={
                0x7A,0x72,0x70
};
uint8_t MYSPI_WDATA[]={
                0x56,0x81,0x55
};

int main()
{
        uint8_t stat,rd;
        uint8_t iset;
        printf("Hello from Nios II!\n");
        IOWR_ALTERA_AVALON_PIO_DIRECTION(PIO_2_BASE, 0x00);
        IOWR_ALTERA_AVALON_PIO_DIRECTION(PIO_3_BASE, 0x00);
        IOWR_ALTERA_AVALON_PIO_DIRECTION(PIO_0_BASE, 0xFF);
        IOWR_ALTERA_AVALON_PIO_DIRECTION(PIO_1_BASE, 0xFF);

        while (1)
        {
                for(iset=0;iset<3;iset++){
                        IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, MYSPI_CONFS[iset]|0x81);
                        IOWR_ALTERA_AVALON_PIO_DATA(PIO_1_BASE, MYSPI_WDATA[iset]);
                        IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, MYSPI_CONFS[iset]|0x80);
                        IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, MYSPI_CONFS[iset]|0x81);
                        stat = IORD_ALTERA_AVALON_PIO_DATA(PIO_2_BASE);
                        while (stat & 0x01)
                        {
                                stat = IORD_ALTERA_AVALON_PIO_DATA(PIO_2_BASE);
                        }
                        rd=IORD_ALTERA_AVALON_PIO_DATA(PIO_3_BASE);
                }
        }

        return 0;
}

こんなコードでやってみます。

こういうピンアサインなので、

pin58とpin59をつないで、MISOでデータ取得できているかどうかも確認したい。

虫の右のドロップダウンからさっき作ったNIOSII環境を選択してデバッグ開始。

やっぱりこれが出るのでYesを押す。(Remember my decisionをつけておけばいいんだろうけど)

こんな感じで止まるので、ブレークポイントをセットしてから継続実行。

止まる。rdにMYSPIが読み取ったデータが入る。変数リストのrdを右クリックしてFormatをHexに変える。とりあえずまだ値は入ってないのでいわゆる不定。

そして継続実行。

読めてる。そして継続実行。

期待通りにできています。

つぎはブレークポイントを外して、継続実行します。

ロジアナで見るとこうなってます。

A0 : SCK

A1 : MOSI

A2 : MISO

A3 : EN

A4 : INIT

A5 : BUSY

となっていて、BUSYのHをSSとしてSPI解析すると、期待通りの値が出力されていることがわかります。また0x55を送っているとき、1Mbit/sとなっており、スピードも期待通りです。

 

FPGAを使うと、一般のマイコンにないような機能や実現できないような機能を比較的たやすく入れられるのでそりゃみんな使いたくなるわな。シミュレーションしやすいのもよい。今回の機能は汎用ロジックのシフトレジスタを使って実現できなくもないけど、たくさんのはんだ付けが必要になる。それがFPGA内で結線できてしまうんだから視力が衰えてきている初老の中年にはそこがなんといっても魅力。

 

とはいえ、この作業を記録に残すのはしんどかった。今まで結構どうでも良いことを途中にさしはさんで書き進めることが多かったけど、今回はほとんどない。そんだけしんどかった。