PL使用中断触发PS

vivado 搭建

顶层触发

  output [2:0]IRQ_F2P_0;
  reg irq1;
  reg irq2;
  reg irq3;
  reg[31:0] cnt;
  always@(posedge sys_clk)
  if(!rst)
  begin
     irq1<=0;
     irq2<=0;
     irq3<=0;
     cnt<=0;
  end
  else
  begin
      if(_cnt >= 32'd49_999_999 && _cnt < 32'd89_999_999)
      begin
          irq1<=0;
          irq2<=1;
          irq3<=0;
          cnt <= 32'd0;
      end
      else if(_cnt >= 32'd89_999_999 && _cnt <32'd100_999_999)
      begin
           irq1<=0;
           irq2<=0;
           irq3<=1;
      end
      else
      begin
          irq1<=1;
          irq2<=0;
          irq3<=0;
          cnt <= cnt + 32'd1;
      end 
  end

SDK中断触发

#include <stdio.h>
#include "xscugic.h"
#include "xil_exception.h"

#define INT_CFG0_OFFSET 0x00000C00

// Parameter definitions
#define IRQ1_INT_ID              61
#define IRQ2_INT_ID              62
#define IRQ3_INT_ID              63
#define INTC_DEVICE_ID          XPAR_PS7_SCUGIC_0_DEVICE_ID
#define INT_TYPE_RISING_EDGE    0x03
#define INT_TYPE_HIGHLEVEL      0x01
#define INT_TYPE_MASK           0x03

static XScuGic INTCInst;

static void IRQ_intr_Handler(void *param);
static int IntcInitFunction(u16 DeviceId);

static void IRQ_intr_Handler(void *param)
{
    int IRQ_id = (int)param;
    printf("IRQ%d int\n\r", IRQ_id);
}

void IntcTypeSetup(XScuGic *InstancePtr, int intId, int intType)
{
    int mask;

    intType &= INT_TYPE_MASK;
    mask = XScuGic_DistReadReg(InstancePtr, INT_CFG0_OFFSET + (intId/16)*4);
    mask &= ~(INT_TYPE_MASK << (intId%16)*2);
    mask |= intType << ((intId%16)*2);
    XScuGic_DistWriteReg(InstancePtr, INT_CFG0_OFFSET + (intId/16)*4, mask);
}

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

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

    // Call to interrupt setup
    Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
                                 (Xil_ExceptionHandler)XScuGic_InterruptHandler,
                                 &INTCInst);
    Xil_ExceptionEnable();

    // Connect IRQ1~IRQ3 interrupt to handler
    status = XScuGic_Connect(&INTCInst,
                             IRQ1_INT_ID,
                             (Xil_ExceptionHandler)IRQ_intr_Handler,
                             (void *)1);
    status = XScuGic_Connect(&INTCInst,
                             IRQ2_INT_ID,
                             (Xil_ExceptionHandler)IRQ_intr_Handler,
                             (void *)2);
    status = XScuGic_Connect(&INTCInst,
                             IRQ2_INT_ID,
                             (Xil_ExceptionHandler)IRQ_intr_Handler,
                             (void *)3);
    if(status != XST_SUCCESS) return XST_FAILURE;


    if(status != XST_SUCCESS) return XST_FAILURE;

    // Set interrupt type of IRQ1~IRQ2 to rising edge
    IntcTypeSetup(&INTCInst, IRQ1_INT_ID, INT_TYPE_RISING_EDGE);
    IntcTypeSetup(&INTCInst, IRQ2_INT_ID, INT_TYPE_RISING_EDGE);
    IntcTypeSetup(&INTCInst, IRQ3_INT_ID, INT_TYPE_RISING_EDGE);
    // Enable SW1~SW2 interrupts in the controller
    XScuGic_Enable(&INTCInst, IRQ1_INT_ID);
    XScuGic_Enable(&INTCInst, IRQ2_INT_ID);
    XScuGic_Enable(&INTCInst, IRQ3_INT_ID);

    return XST_SUCCESS;
}

int main(void)
{
    print("PL IRQ test\n\r");
    IntcInitFunction(INTC_DEVICE_ID);
    while(1);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/wangjie36/article/details/121132212
今日推荐