MicroBlazeでAXI GPIOの外部ピン割り込みを実装

概要

MicroBlazeで外部ピンからの割り込みを実装し、AXI GPIOのInterruptとAXI Interrupt Controllerの使い方を学びます。

ハードウェア

MicroBlaze
・AXI GPIO (Enable Interruptを有効にする)
・AXI Interrupt Controller
をBlock Designに追加する。

AXI GPIOのip2intc_irptをConcatを挟みAXI Interrupt Controllerのintrに接続する。

ソースコード

#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xintc.h"
#include "xgpio.h"

#define GPIO1 1
#define GPIO2 2

XGpio Gpio;
XIntc Intc;

// GPIO Interrupt Handler
void GpioHandler(void *CallbackRef)
{
    XGpio *GpioPtr = (XGpio *)CallbackRef;
    xil_printf("Gpio Interrupt!\r\n");
    // Clear the Interrupt
    XGpio_InterruptClear(GpioPtr, 1);
}

int main()
{
    int Status;

    // XGpioの初期化
    Status = XGpio_Initialize(&Gpio, XPAR_GPIO_0_DEVICE_ID);
    if(Status != XST_SUCCESS) return XST_FAILURE;
    XGpio_SetDataDirection(&Gpio, 1, 1);

    // XIntcの初期化
    Status = XIntc_Initialize(&Intc, XPAR_INTC_0_DEVICE_ID);
    if(Status != XST_SUCCESS) return XST_FAILURE;

    // XGpioの割り込みで呼び出される関数を指定
    Status = XIntc_Connect(&Intc, XPAR_INTC_0_GPIO_0_VEC_ID,
                (XInterruptHandler)GpioHandler,
                (void *)&Gpio);
    if(Status != XST_SUCCESS) return XST_FAILURE;

    //XIntcをhardware interrupts onlyで開始
    Status = XIntc_Start(&Intc, XIN_REAL_MODE);
    if(Status != XST_SUCCESS) return XST_FAILURE;

    // XGpioの割り込みを有効化
    XIntc_Enable(&Intc, XPAR_INTC_0_GPIO_0_VEC_ID);

    // MicroBlazeの割り込み設定を初期化
    Xil_ExceptionInit();
    // MicroBlazeにXIntcからの割り込みを登録
    Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
                (Xil_ExceptionHandler)XIntc_InterruptHandler,
                &Intc);
    // MicroBlazeの割り込みを有効化
    Xil_ExceptionEnable();

    // GPIOの割り込みを有効化
    XGpio_InterruptEnable(&Gpio, GPIO1);
    // GPIOのグローバル割り込みを有効化
    XGpio_InterruptGlobalEnable(&Gpio);

    while(1);
    cleanup_platform();
    return 0;
}

実行結果

AXI GPIOに接続したボタンスイッチを押すと
「GPIO Interrupt!」と表示されます。