강의

멘토링

커뮤니티

인프런 커뮤니티 질문&답변

anstjdqls55님의 프로필 이미지
anstjdqls55

작성한 질문수

Verilog ZYNQ Program 1 (Zynq mini 7020)

P127~129 교안내용

작성

·

24

·

수정됨

0

6-4내용 교안에서

함수 IntcInitFunction, InterruptSystemSetup에 대해서 정의를 안해줘서 코드가 안돌아갑니다.

그리고 KeyIntrHandler 함수에서 if (keyVal == 0)으로 주면 버튼을 눌러야 off처리 되고 때면 on처리가 됩니다. 제 생각에는 if (keyVal)로 해야 교안 방향처럼 버튼을 누르면 on이 되고 떼면 off가 되는 로직이 되는거 같습니다. 맞나요?

총 코드는 아래와 같이 작성했습니다. 그러니까 잘 동작하네요:)


#include <stdio.h>
#include "platform.h"
#include "xparameters.h"
#include "xscugic.h"
#include "xil_exception.h"
#include "xgpio.h"
#include <unistd.h>

#define INTC_DEVICE_ID          XPAR_PS7_SCUGIC_0_DEVICE_ID
#define KEY_DEVICE_ID           XPAR_AXI_GPIO_0_DEVICE_ID
#define LED_DEVICE_ID           XPAR_AXI_GPIO_1_DEVICE_ID
#define INTC_GPIO_INTERRUPT_ID  XPAR_FABRIC_AXI_GPIO_0_IP2INTC_IRPT_INTR
#define KEY_INT_MASK            XGPIO_IR_CH1_MASK
XGpio   LEDInst;
XGpio   KEYInst;
XScuGic INTCInst;
u32 	KeyIntRisingFlag    = 0;
u32 	KeyIntFallingFlag   = 0;

static void KeyIntrHandler(void * InstancePtr);
static int IntcInitFunction(u16 DeviceId, XGpio * GpioInstancePtr);
static int InterruptSystemSetup(XScuGic * XScuGicInstancePtr);

int main()
{
    init_platform();
    int status;

    status = XGpio_Initialize(&KEYInst, KEY_DEVICE_ID); // initial KEY
    if(status != XST_SUCCESS) return XST_FAILURE;

    status = XGpio_Initialize(&LEDInst, LED_DEVICE_ID);  // initial LED
    if(status != XST_SUCCESS)return XST_FAILURE;

    XGpio_SetDataDirection(&KEYInst, 1, 0xFF);
    XGpio_SetDataDirection(&LEDInst, 1, 0); // set LED IO direction as out
    XGpio_DiscreteWrite(&LEDInst, 1, 0x00);// at initial, all LED turn off

    printf(">>Press PL KEY1, and check the PL LED1 \n");
    status = IntcInitFunction(INTC_DEVICE_ID, &KEYInst);
    if(status != XST_SUCCESS)return XST_FAILURE;

    while (1)
    {
        if (KeyIntFallingFlag == 1)
        {
        	KeyIntFallingFlag = 0;
            printf(" - interrupt falling occur, led on \r\n");
            XGpio_DiscreteWrite(&LEDInst, 1, 0xFF);
        }

        if (KeyIntRisingFlag == 1)
        {
        	KeyIntRisingFlag = 0;
        	printf(" - interrupt rising occur, led off \r\n");
        	XGpio_DiscreteWrite(&LEDInst, 1, 0);
        }
    }

    cleanup_platform();
    return 0;
}

static void KeyIntrHandler(void * InstancePtr)
{
    u8 keyVal;
    usleep(10000); // 0.1s sleep, to debounce, in common, the meta-state will sustain no more than 20ms
    keyVal = XGpio_DiscreteRead(&KEYInst, 1) & 0x0f;

    if (keyval)   KeyIntFallingFlag = 1;
    else       	  	   KeyIntRisingFlag  = 1;

    XGpio_InterruptClear(&KEYInst, KEY_INT_MASK);
    XGpio_InterruptEnable(&KEYInst, KEY_INT_MASK);  // Enable GPIO interrupts
}

static int IntcInitFunction(u16 DeviceId, XGpio * GpioInstancePtr)
{
    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 interrupt setup function
    status = InterruptSystemSetup(&INTCInst);
    if(status != XST_SUCCESS) return XST_FAILURE;

    // Register GPIO interrupt handler
    status = XScuGic_Connect(&INTCInst, INTC_GPIO_INTERRUPT_ID,
            (Xil_ExceptionHandler)KeyIntrHandler, (void*)GpioInstancePtr);
    if(status != XST_SUCCESS)return XST_FAILURE;
    // Enable GPIO interrupts
    XGpio_InterruptEnable(GpioInstancePtr, 1);
    XGpio_InterruptGlobalEnable(GpioInstancePtr);
    // Enable GPIO interrupts in the controller
    XScuGic_Enable(&INTCInst, INTC_GPIO_INTERRUPT_ID);
    return XST_SUCCESS;
}

//----------------------------------------------------------------------------
// Interrupt system setup
//----------------------------------------------------------------------------
static int InterruptSystemSetup(XScuGic * XScuGicInstancePtr)
{
    // Register GIC interrupt handler
    Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
            (Xil_ExceptionHandler)XScuGic_InterruptHandler, XScuGicInstancePtr);
    Xil_ExceptionEnable();
    return XST_SUCCESS;
}

 

 

 

 

 

 

 

답변 1

0

alex님의 프로필 이미지
alex
지식공유자

안녕하세요.

  1. IntcInitFunction, InterruptSystemSetup 함수 선언은 되어 있습니다. 강의 자료 보시면 127페이지의 소스 설명 73-74 라인 참조하세요

  2. KeyVal 에 대한 내용 : 회로도를 보시면 (9페이지) FPGA_PL_KEY1 신호가 K2 스위치가 눌러지면 0 값이 입력되고, 스위치를 떼면 1 값이 입력됩니다. 강의 내용은 이 신호를 기준으로 프로그램 되었습니다. 즉 스위치를 누르는 순간(1 -> 0)을 falling 신호로 보고, 스위치를 떼는 순간(0->1)을 rising 으로 보았습니다.

강의 내용은 제가 프로그램을 직접하고 보드에 올려서 확인한 내용을 기반으로 하고 있습니다. 그러나 혹시 모를 오류가 있을 수는 있으니 이해 부탁 드립니다.

강의 내용이 쉬운 내용은 아닙니다. 강의 내용대로 열심히 하시는 모습에 응원을 보내드립니다. fpga 프로그램이 배우기도 어렵고 시간도 많이 소요됩니다. 그러나 열심히 하다보면 감이 생기고 자신감이 생기게 됩니다. 제가 보기에는 프로그램을 내 마음대로 다룰 수 있을 정도가 되면 현업에서 프로젝트를 진행하시는데 충분할 것으로 생각합니다. 끝까지 강의 완주하시고 이해가 안 되시는 부분은 반복해서 공부하시길 바랍니다.

감사합니다 ~!!

 

anstjdqls55님의 프로필 이미지
anstjdqls55

작성한 질문수

질문하기