概要
Xilinx AXI GPIOをZynqやMicroblazeで使う方法について、公式のBaremetal Driverを使って書いていきます。
環境
- Vivado 2018.3
Bitstreamの作成
2個のLEDをGPIO1に、2個のスイッチをGPIO2に接続しました。
GPIO1はAll Outputs
、GPIO2はAll Inputs
のフラグを有効にしています。
サンプルコード
いきなりですが、LEDの点灯とスイッチの読取りを行うコードは下記のとおりです。
Hello World
のテンプレートにこれをコピペすれば初期化と基本動作を試せます。
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xgpio.h"
#define LED_CHANNEL 1
#define SW_CHANNEL 2
XGpio gpio_0;
int main(){
int status;
init_platform();
// AXI GPIOドライバの初期化
status = XGpio_Initialize(&gpio_0, XPAR_GPIO_0_DEVICE_ID);
if(status != XST_SUCCESS){
xil_printf("XPAR_GPIO_0_DEVICE_ID initialization failed.\n");
return XST_FAILURE;
}
// 入出力方向の設定 0:出力 1:入力
XGpio_SetDataDirection(&gpio_0, LED_CHANNEL, 0x0); // all output
XGpio_SetDataDirection(&gpio_0, SW_CHANNEL, 0xFFFFFFFF); // all input
// LED点灯 (32bitを一度にセット)
XGpio_DiscreteWrite(&gpio_0, LED_CHANNEL, 0b11);
// 指定したビットだけクリア (0にセット)
XGpio_DiscreteClear(&gpio_0, LED_CHANNEL, (1<<1));
// 指定したビットだけセット (1にセット)
XGpio_DiscreteSet(&gpio_0, LED_CHANNEL, (1<<0));
// スイッチの値を読み出し
u32 sw_state = XGpio_DiscreteRead(&gpio_0, SW_CHANNEL);
xil_printf("SW=%08x\n", sw_state);
cleanup_platform();
return 0;
}
Interruptの有効化
// AXI GPIOの割り込みを有効化 (GPIO2のみ有効)
XGpio_InterruptEnable(&gpio_0, SW_CHANNEL);
// AXI GPIOのグローバル割り込みを有効化
XGpio_InterruptGlobalEnable(&gpio_0);
// 割り込みハンドラ
void GpioHandler(void *CallbackRef){
XGpio *GpioPtr = (XGpio *)CallbackRef;
// 割り込みをクリア
XGpio_InterruptClear(GpioPtr, SW_CHANNEL);
}
MicroBlazeでGPIO割り込みをテストした記事はこちらです。
http://taltalp.hatenablog.jp/entry/2018/09/24/005413
参考
私が以前書いたブログですが、ブログ名が原因で記事が検索しにくかったのでQiitaに再掲載しています。
http://taltalp.hatenablog.jp/entry/2017/11/06/204748