AXI GPIOについて

概要

AXI GPIOの使い方についてのメモ書きです。

AXI GPIOはFPGAのピンの入出力としてももちろん使えますが、
FPGA内部のIPの入出力をコントロールすることもできて非常に便利なIPです。

Vivadoプロジェクトの作成

Block DesignなどでAXI GPIOを追加するだけなので、省略します。

SDKプロジェクトの作成

LEDを点灯するサンプルコードを下記に示します。

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

// Gpio構造体
XGpio Gpio_led;

int main()
{
    int Status;

    init_platform();

    // AXI GPIOの初期化
    Status = XGpio_Initialize(&Gpio_led, XPAR_AXI_GPIO_0_DEVICE_ID);
    if (Status != XST_SUCCESS){
    	xil_printf("XPAR_AXI_GPIO_0_DEVICE_ID initialize failed\n\r");
    	return XST_FAILURE;
    }

    // AXI GPIOの入出力設定
    XGpio_SetDataDirection(&Gpio_led, 1, 0); // all output

    // AXI GPIOの出力値設定
    XGpio_DiscreteWrite(&Gpio_led, 1, 0x1); // led high

    cleanup_platform();
    return 0;
}

AXI GPIOの初期化

int XGpio_Initialize(XGpio *InstancePtr, u16 DeviceId);

でAXI GPIOが初期化されます。

DeviceIdはxparameters.hを見て、初期化したいAXI GPIOのDeviceIdを設定してください。

IPの初期化に成功するとXST_SUCCESSが返ってきます。
それ以外の場合はデバイスIDが間違っていたり、AXI GPIOがなかったりする可能性があります。
今回は初期化に失敗したらXST_FAILUREを返してプログラムを修了するようにしています。

AXI GPIOの入出力設定

void XGpio_SetDataDirection(XGpio *InstancePtr, unsigned Channel,
			    u32 DirectionMask);

で使用するピンの入出力方向を設定します。

Channelには「1」か「2」の値が入ります。
AXI GPIOはチャネルが2つまで設定できます。
どちらのチャネルを設定するのか、それぞれ決めなければいけません。
今回はチャネル1のみ使用するため1を設定しました。

DirectionMaskで入出力方向を決めます。
各bitは
0:出力
1:入力
となります。

AXI GPIOの出力値設定

void XGpio_DiscreteWrite(XGpio *InstancePtr, unsigned Channel, u32 Mask);

でピンの出力値が設定できます。
Maskで出力値のHigh/Lowを切り替えます。
各bitは
0:Low
1:High
となります。

AXI GPIOの入力値読み出し

u32 XGpio_DiscreteRead(XGpio *InstancePtr, unsigned Channel);

でピンの入力値が読み出せます。
予め各ピンは入力と設定されている必要があります。

AXI GPIOのビットセット/クリア

void XGpio_DiscreteSet(XGpio *InstancePtr, unsigned Channel, u32 Mask);
void XGpio_DiscreteClear(XGpio *InstancePtr, unsigned Channel, u32 Mask);

でビット単位でセット/クリアができます。

割り込み設定

AXI GPIOのIP設定画面から割り込みを有効にすることができます。

void XGpio_InterruptGlobalEnable(XGpio *InstancePtr);
void XGpio_InterruptGlobalDisable(XGpio *InstancePtr);
void XGpio_InterruptEnable(XGpio *InstancePtr, u32 Mask);
void XGpio_InterruptDisable(XGpio *InstancePtr, u32 Mask);
void XGpio_InterruptClear(XGpio *InstancePtr, u32 Mask);
u32 XGpio_InterruptGetEnabled(XGpio *InstancePtr);
u32 XGpio_InterruptGetStatus(XGpio *InstancePtr);

という関数があります。

これらについてはまた機会があれば書こうかと思います。