LoginSignup
1
2

More than 5 years have passed since last update.

Zybo > Interrupt > AXI Timer > LEDを点灯する処理

Last updated at Posted at 2016-05-28

割込み

割込みを使ったTimer処理を試用した。

以下の動画で手順が紹介されている。
https://www.youtube.com/watch?v=gaZ1kRJzCok&list=PL_MJualihC5CAtnZHphK-hli8aSL3PRRz&index=39

Vivadoでの処理

  1. IPリストからZynqを追加
  2. IPリストからGPIOを追加
  3. Run Connection Automationからaxi_gpio_0 > S_AXIを選択
    • Clock: Auto
  4. Run Connection Automationからaxi_gpio_0 > GPIOを選択
    • Select Board Part Interface: leds_4bitsを選択
  5. IPリストからAXI Timerを追加
  6. Run Connection Automationからaxi_timer_0 > S_AXIを選択
    • Clock: Auto
  7. ZynqのIPをダブルクリック > Interruptsのページに移動
  8. Fabric Interruptsをチェック
    • IRQ_F2P[15:0]をチェック
  9. axi_timer_0のinterruptとZYNQのIRQ_F2Pを接続
  10. Validate Designでエラーがないか確認
  11. Sources > Design Sources > design_XXXにて右クリックしてCreate HDL Wrapperを選択
    • Let Vivado manage wrapper and auto-update
  12. Generate Bitstream

作成したものをXSDKにExportして、XSDKを起動する。

XSDKでの処理

  1. New -> Application Project
    • Project name: Timer_LED
    • Hello Worldテンプレートで作成
  2. helloworld.cを編集 (後述)
  3. Program FPGA実行
  4. helloworldを実行

基板上のLED(写真左下のスイッチの上にある4つのLED)が点灯していく動作が確認できた。

DSC_0169.JPG

code

上記のリンクのビデオを見ながら写経した。

helloworld.c
#include <stdio.h>
#include "platform.h"

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

// Parameter definitions
#define INTC_DEVICE_ID  XPAR_PS7_SCUGIC_0_DEVICE_ID
#define TMR_DEVICE_ID   XPAR_TMRCTR_0_DEVICE_ID
#define LEDS_DEVICE_ID  XPAR_AXI_GPIO_0_DEVICE_ID
#define INTC_TMR_INTERRUPT_ID   XPAR_FABRIC_AXI_TIMER_0_INTERRUPT_INTR

#define TMR_LOAD    0xF8000000

XGpio LEDInst;
XScuGic INTCInst;
XTmrCtr TMRInst;

static int led_data;
static int tmr_count;

// -------- function prototypes
static void TMR_Intr_Handler(void *baseaddr_p);
static int IntcInitFunction(u16 DeviceId, XTmrCtr *TmrInstancePtr);


void TMR_Intr_Handler(void *data)
{
    if (XTmrCtr_IsExpired(&TMRInst, 0)) {
        if (tmr_count == 3) {
            XTmrCtr_Stop(&TMRInst, 0);
            tmr_count = 0;
            led_data++;
            XGpio_DiscreteWrite(&LEDInst, 1, led_data);
            XTmrCtr_Reset(&TMRInst, 0);
            XTmrCtr_Start(&TMRInst, 0);
        } else {
            tmr_count++;
        }
    }
}

int InterruptSystemSetup(XScuGic *XScuGicInstancePtr)
{
    Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
            (Xil_ExceptionHandler) XScuGic_InterruptHandler,
            XScuGicInstancePtr);
    Xil_ExceptionEnable();

    return XST_SUCCESS;
}

int IntcInitFunction(u16 DeviceId, XTmrCtr *TmrInstancePtr)
{
    XScuGic_Config *IntcConfig;
    int status;

    // Interrupt controller initialization
    IntcConfig = XScuGic_LookupConfig(DeviceId);
    status = XScuGic_CfgInitialize(&INTCInst, IntcConfig,
            IntcConfig->CpuBaseAddress);
    if (status != XST_SUCCESS) {
        return XST_FAILURE;
    }

    // Call to interupt setup
    status = InterruptSystemSetup(&INTCInst);
    if (status != XST_SUCCESS) {
        return XST_FAILURE;
    }

    // Connect timer interrupt to handler
    status = XScuGic_Connect(&INTCInst, INTC_TMR_INTERRUPT_ID,
            (Xil_ExceptionHandler) TMR_Intr_Handler, (void *) TmrInstancePtr);
    if (status != XST_SUCCESS) {
        return XST_FAILURE;
    }

    // Enable timer interrupt in the controller
    XScuGic_Enable(&INTCInst, INTC_TMR_INTERRUPT_ID);

    return XST_SUCCESS;
}

int main()
{
    init_platform();

    led_data = 0;

    int status;

    // Init GPIO
    status = XGpio_Initialize(&LEDInst, LEDS_DEVICE_ID);
    if (status != XST_SUCCESS) {
        return XST_FAILURE;
    }

    XGpio_SetDataDirection(&LEDInst, 1, 0x00);

    // Init GIC
    status = IntcInitFunction(INTC_DEVICE_ID, &TMRInst);
    if (status != XST_SUCCESS) {
        return XST_FAILURE;
    }

    // Setup Timer
    status = XTmrCtr_Initialize(&TMRInst, TMR_DEVICE_ID);
    if (status != XST_SUCCESS) {
        return XST_FAILURE;
    }

    XTmrCtr_SetHandler(&TMRInst, (XTmrCtr_Handler) TMR_Intr_Handler, &TMRInst);
    XTmrCtr_SetResetValue(&TMRInst, 0, TMR_LOAD);
    XTmrCtr_SetOptions(&TMRInst, 0,
            XTC_INT_MODE_OPTION | XTC_AUTO_RELOAD_OPTION);
    XTmrCtr_Start(&TMRInst, 0);

    while(1)
        ;
}
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2