FC2カウンター FPGAの部屋 axi_timerを使う2(割り込みを使用した)
FC2ブログ

FPGAやCPLDの話題やFPGA用のツールの話題などです。 マニアックです。 日記も書きます。

FPGAの部屋

FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。Xilinx ISEの初心者の方には、FPGAリテラシーおよびチュートリアルのページをお勧めいたします。

axi_timerを使う2(割り込みを使用した)

”axi_timerを使う1"で、ポーリングでは、axi_timerを使うことができたが、割り込みでは使えなかった、今回はその理由を探ってみることにした。

まずは、ネットを検索して、MicroBlazeの割り込みに関しての資料を探した。その結果、
Using and Creating Interrupt-Based Systems XAPP778 (v1.0) January 11, 2005
エンベデッド システムツール リファレンス マニュアル EDK10.1 サービス パック1”の付録B 割り込み制御
がわかった。

さて、XPSを起動して、Portsタブをクリックし、axi_timerを展開してみる。Interruptはaxi_timer_0_Interrupt信号に接続されている。
SP605_AXI_CDC_42_110814.png

次に、microblaze_0 を展開してみてみると、Interruptはmicroblaze_0_interrupt 信号に接続されている。
SP605_AXI_CDC_43_110814.png

microblaze_0 のInterrupt をaxi_timer_0_Interruptにつなぎ変えてみた。
SP605_AXI_CDC_44_110814.png

ProjectメニューからRescan User Repositories を選択して、リポジトリを作りなおす。
ISE(Project Navigator) で再度インプリメントした。

SDKを立ち上げ、ビットファイルをダウンロードして、デバックモードで実行したら、割り込みを使用したプログラムが正常に実行できた。そのプログラムを下に示す。

/* * axi_timer_test.c * *  Created on: 2011/08/12 *      Author: Masaaki */

#include "xbasic_types.h"
#include "xio.h"
#include "mb_interface.h"
#include "xparameters.h"

#define AXI_TIMER_0_TCSR0    XPAR_AXI_TIMER_0_BASEADDR    // Control/Status Register 0
#define AXI_TIMER_0_TLR0    XPAR_AXI_TIMER_0_BASEADDR+0x4    // Load Register 0
#define AXI_TIMER_0_TCR0    XPAR_AXI_TIMER_0_BASEADDR+0x8    // Timer/Counter Register 0
#define AXI_TIMER_0_TCSR1    XPAR_AXI_TIMER_0_BASEADDR+0x10    // Control/Status Register 1
#define AXI_TIMER_0_TLR1    XPAR_AXI_TIMER_0_BASEADDR+0x14    // Load Register 1
#define AXI_TIMER_0_TCR1    XPAR_AXI_TIMER_0_BASEADDR+0x18    // Timer/Counter Register 1

#define ENABLE_ALL_TIMERS                (0x1<<10)
#define ENABLE_PULSE_WIDTH_MODULATION    (0x1<<9)
#define    TIMER_INTERRUPT                    (0x1<<8)
#define ENABLE_TIMER                    (0x1<<7)
#define ENABLE_INTERRUPT                (0x1<<6)
#define LOAD_TIMER                        (0x1<<5)
#define AUTO_RELOAD_HOLD_TIMER            (0x1<<4)
#define ENABLE_EXT_CAPTURE_TRIG            (0x1<<3)
#define ENABLE_EXT_GENERATE_SIG            (0x1<<2)
#define DOWN_UP_COUNT_TIMER                (0x1<<1)
#define TIMER_MODE_CAP_GENE                (0x1)

int interrupt = 0;

void axi_timer_init(){
    *(volatile *)(AXI_TIMER_0_TLR0) = 0x004C4B40; // 0.1秒
    // *(volatile *)(AXI_TIMER_0_TLR0) = 0x00989680; // 0.2秒
    *(volatile *)(AXI_TIMER_0_TCSR0) = ENABLE_ALL_TIMERS | LOAD_TIMER; // TLR0へロード
    *(volatile *)(AXI_TIMER_0_TCSR0) = ENABLE_ALL_TIMERS | ENABLE_TIMER | ENABLE_INTERRUPT | AUTO_RELOAD_HOLD_TIMER | DOWN_UP_COUNT_TIMER; // GenerateモードでDWONカウント、割り込みあり、オートロードあり
}

void timer_int_handler(void * arg) {
    interrupt = 1;
}

void write_data(unsigned int address, unsigned int data)
{
    *(volatile *)(XPAR_CHARDISPC_0_BASEADDR) = address;
    *(volatile *)(XPAR_CHARDISPC_0_BASEADDR+4) = data;
}

int read_data(unsigned int address)
{
    *(volatile *)(XPAR_CHARDISPC_0_BASEADDR) = address;
    return(*(volatile *)(XPAR_CHARDISPC_0_BASEADDR+4));
}

int main()
{
    unsigned int addr;
    unsigned int color, char_code, data;
    unsigned int temp;

    axi_timer_init(); // axi_timerの初期化

    // 割り込みハンドラ登録、割り込み許可
    microblaze_register_handler(timer_int_handler, (void *) 0);
    microblaze_enable_interrupts();

    for(addr=0, color=1, char_code=0x21; addr < 100*75; addr++, color++, char_code++){
        data = (color & 0x7)<<7 | char_code;
        write_data(addr, data);
        if (char_code == 0x7e) // キャラクタの~
            char_code = 0x20// キャラクタの!
        if ((color & 0x7) == 7)
            color = 0;

        // axi_timter割り込み待ち
        interrupt = 0;
        while(interrupt==0);
        *(volatile *)(AXI_TIMER_0_TCSR0) = ENABLE_ALL_TIMERS | ENABLE_TIMER | ENABLE_INTERRUPT | AUTO_RELOAD_HOLD_TIMER | DOWN_UP_COUNT_TIMER | TIMER_INTERRUPT;

    }

    return 0;
}


  1. 2011年08月14日 20:45 |
  2. EDK
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック URL
https://marsee101.blog.fc2.com/tb.php/1878-c3f0b0ef
この記事にトラックバックする(FC2ブログユーザー)