FC2カウンター FPGAの部屋 Zynq で PL から PS に割り込みを掛ける2
fc2ブログ

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

FPGAの部屋

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

Zynq で PL から PS に割り込みを掛ける2

Zynq で PL から PS に割り込みを掛ける1”の続き。

FPGAプログラミング大全 Xilinx編 第2版”の”5-4 タイマー割り込みとAPIの利用”の second プロジェクトを改造して、プッシュボタンスイッチを押した時に割り込みを掛けて RGB LED のON/OFF 制御をしてみようということで、前回は、前振りとして、PL から PS への割り込み方法について調査した。今回は、 second プロジェクトのブロックデザインに押しボタンスイッチによって PL から PS への割り込みを追加する。

まずは second プロジェクトのブロックデザインで processing_system7_0 をダブルクリックして設定画面を開く。

Page Navigator で Interrupt をクリックする。
Fabric Interrupt -> PL-PS Interrupt Ports を展開する。
IRG_F2P[15:0] にチェックを入れる。
second_53_210214.png

processing_system7_0 に IRQ_F2P[0:0] が増えた。
BTN[1:0] を IRQ_F2P[0:0] に接続するのだが、”Zynq で PL から PS に割り込みを掛ける1”に書いたとおりに、 Slice で BTN[1] と BTN{0] に分けてから Concat でまとめて IRQ_F2P[0:0] に入れる。まだ IRQ_F2P[0:0] のままになっている。(なお、このブロックデザインでは、 Slice を接続する Concat のポートが間違っている。Sletected_bit1 の Slice が Concat の In1 に接続されるはずだ)
second_54_210214.png

論理合成、インプリメンテーション、ビットストリームの生成後のブロックデザインを示す。(この時は、Sletected_bit1 の Slice が Concat の In1 に接続されていて、バグが修正されている)
second_55_210214.png

IRQ_F2P[1:0] に修正されていて、正常なビット長になっている。

Project Summary を示す。
second_56_210214.png

ハードウェアをエクスポートして、 XSA ファイルを更新した。

Vitis で design_1_wrapper プラットフォームを右クリックし右クリックメニューから Update Hardware Specification を選択する。
Update Hardware Specification ダイアログが表示される。更新した XSA ファイルを指定して、プラットフォームをアップデートする。
プラットフォームを再度ビルドする。
second_lef_off アプリケーション・プロジェクトを新規作成した。
second_led_off_system -> second_led_off -> src を右クリックし右クリックメニューから New -> File を選択して、 second_led_off.c を新規作成した。
ソースコードは ”FPGAプログラミング大全 Xilinx編 第2版”の”5-4 タイマー割り込みとAPIの利用”の second.c を改造して使用している。
second_57_210215.png

これで、アプリケーション・ソフトウェアを Run すると、 second プロジェクトと同様に RGB LED が色を変えながら点灯する。
そして、BTN0 で RGB LED の点灯が停止して、 BTN1 で RGB LED の点灯が再開した。成功だ。

最後に、小林様のご厚意で、 second_lef_off.c の全文を掲載させていただく。

/* Copyright(C) 2020 Cobac.Net All Rights Reserved. */
/* chapter: 第5章                  */
/* Vivado : second                 */
/* Vitis  : second                 */
/* outline: タイマー割り込みテスト */

// second_led_off.c 2021/02/14 by marsee
// second.c にPLの割り込みを追加して BTN0 でLED OFF、BTN1で LED ON するようにコードを変更した

#include "xparameters.h"
#include "xgpio.h"
#include "xscutimer.h"
#include "xscugic.h"
#include "xil_exception.h"
#include "xil_printf.h"

#define TIMER_LOAD_VALUE 333333333  /* CPU周波数667MHzの1/2 */
#define LED_CHANNEL      1          /* ch1:LED ch2:BTN      */

/* 各周辺回路のインスタンス変数 */
XGpio Gpio;
XScuTimer TimerInstance;
XScuGic IntcInstance;

int led_stat = 1;

/* LED表示パターン作成 */
int led_rgb(int cnt)
{
    int led;
    switch ( cnt%5 ) {
        case 0: led = 0x4; break;
        case 1: led = 0x2; break;
        case 2: led = 0x1; break;
        case 3: led = 0x7; break;
        case 4: led = 0x0; break;
        default:led = 0x0;
    }
    return led;
}

/* タイマー割り込み関数 */
void TimerCounterHandler(void *CallBackRef)
{
    volatile static int cnt;
    XScuTimer *TimerInstancePtr = (XScuTimer *) CallBackRef;

    if (XScuTimer_IsExpired(TimerInstancePtr)) {
        XScuTimer_ClearInterruptStatus(TimerInstancePtr);
        if (led_stat == 1){
            if ( ++cnt>9 ) cnt = 0;
        }else{
            cnt = 4;
        }
        xil_printf("cnt=%d\n", cnt);
        XGpio_DiscreteWrite(&Gpio, LED_CHANNEL, led_rgb(cnt));
    }
}

// LED_on 割り込み関数
void LED_ON_Handler(void *CallBackRef){
    led_stat = 1;
}

// LED_off 割り込み関数
void LED_OFF_Handler(void *CallBackRef){
    led_stat = 0;
}

/* 割り込みコントローラのドライバ初期化 */
int ScuGicInt_Init( void )
{
    int Status;
    XScuGic_Config *ConfigPtr;
    ConfigPtr = XScuGic_LookupConfig(XPAR_PS7_SCUGIC_0_DEVICE_ID);
    Status = XScuGic_CfgInitialize(&IntcInstance, ConfigPtr,
            ConfigPtr->CpuBaseAddress);
    if (Status != XST_SUCCESS) return XST_FAILURE;
    Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
            (Xil_ExceptionHandler) XScuGic_InterruptHandler,
            &IntcInstance);
    Xil_ExceptionEnable();
    return XST_SUCCESS;
}

/* 割り込み処理関数の登録 */
int ScuGicInt_Reg(u32 Int_Id, void *InstancePtr, void *IntHandler)
{
    int Status;
    Status = XScuGic_Connect(&IntcInstance,
            Int_Id,
            (Xil_ExceptionHandler)IntHandler,
            (void *)InstancePtr);
    if (Status != XST_SUCCESS) return XST_FAILURE;
    XScuGic_Enable(&IntcInstance, Int_Id);
    return XST_SUCCESS;
}

int main()
{
    int Status;
    XScuTimer_Config *ConfigPtr;

    xil_printf("Timer Interrupt Test.\n\n");

    /* GPIOの初期化 */
    Status = XGpio_Initialize(&Gpio, XPAR_GPIO_0_DEVICE_ID);
    if (Status != XST_SUCCESS) return XST_FAILURE;
    XGpio_SetDataDirection(&Gpio, LED_CHANNEL, 0);
    XGpio_DiscreteWrite(&Gpio, LED_CHANNEL, led_rgb(0));

    /* タイマーのドライバ初期化 */
    ConfigPtr = XScuTimer_LookupConfig(XPAR_XSCUTIMER_0_DEVICE_ID);
    Status = XScuTimer_CfgInitialize(&TimerInstance, ConfigPtr,
                    ConfigPtr->BaseAddr);
    if (Status != XST_SUCCESS) return XST_FAILURE;

    /* 割り込み関連初期化と割り込み処理関数の登録 */
    Status = ScuGicInt_Init();
    if (Status != XST_SUCCESS) return XST_FAILURE;
    Status = ScuGicInt_Reg(XPAR_SCUTIMER_INTR, &TimerInstance,
                           TimerCounterHandler);
    if (Status != XST_SUCCESS) return XST_FAILURE;

    // BTN 1 , LED ON
    Status = XScuGic_Connect(&IntcInstance,
            XPS_FPGA1_INT_ID,
            (Xil_ExceptionHandler)LED_ON_Handler,
            (void *)NULL);
    if (Status != XST_SUCCESS) return XST_FAILURE;
    XScuGic_Enable(&IntcInstance, XPS_FPGA1_INT_ID);

    // BTN 0 , LED OFF
    Status = XScuGic_Connect(&IntcInstance,
            XPS_FPGA0_INT_ID,
            (Xil_ExceptionHandler)LED_OFF_Handler,
            (void *)NULL);
    if (Status != XST_SUCCESS) return XST_FAILURE;
    XScuGic_Enable(&IntcInstance, XPS_FPGA0_INT_ID);

    /* タイマーの初期設定と開始 */
    XScuTimer_EnableAutoReload(&TimerInstance);
    XScuTimer_LoadTimer(&TimerInstance, TIMER_LOAD_VALUE);
    XScuTimer_EnableInterrupt(&TimerInstance);
    XScuTimer_Start(&TimerInstance);

    while(1);
    return 0;
}


  1. 2021年02月18日 03:35 |
  2. Zynq
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


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

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