ZYNQ PL IRQ PS

/*
 * Copyright (c) 2009 Xilinx, Inc.  All rights reserved.
 *
 * Xilinx, Inc.
 * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
 * COURTESY TO YOU.  BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
 * ONE POSSIBLE   IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
 * STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
 * IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
 * FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
 * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
 * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
 * ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
 * FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 */

/*
 * helloworld.c: simple test application
 */

/***************************** Include Files ********************************/
#include <stdio.h>
#include "platform.h"
#include "xil_io.h"
#include "xil_mmu.h"
#include "xil_exception.h"
#include "xpseudo_asm.h"
#include "xil_types.h"
#include "xparameters.h"
#include "xparameters_ps.h"
#include "xplatform_info.h"
#include "xil_printf.h"
#include "math.h"
#include "xscutimer.h"
#include "xil_cache.h"
#include "xscugic.h"
#include "sleep.h"
#include "xreg_cortexa9.h"
#include "xil_assert.h"
#include "xdebug.h"
#include "xtime_l.h"


/************************** Constant Definitions ****************************/
#define INTC		    			XScuGic
#define INTC_DEVICE_ID				XPAR_PS7_SCUGIC_0_DEVICE_ID
#define INTC_HANDLER				XScuGic_InterruptHandler
#define PL_IRQ_ID       			XPS_IRQ_INT_ID
#define IRQ_PCORE_GEN_BASE  		XPAR_IRQ_GEN_0_BASEADDR
#define XPAR_IRQ_GEN_0_BASEADDR 	0x10000000


/**************************** Type Definitions ******************************/
typedef struct {
	u16 DeviceId;		/**< Unique ID of device */
	u32 BaseAddress;	/**< Base address of the device */
} Pl_Config;

typedef struct {
	Pl_Config Config;   /**< Hardware Configuration */
	u32 IsReady;		/**< Device is initialized and ready */
	u32 IsStarted;		/**< Device is running */
} XPlIrq;


/***************** Macros (Inline Functions) Definitions ********************/

/************************** Variable Definitions ****************************/
/* Assign the driver structures for the interrupt controller */
/* 为中断控制器分配驱动程序结构 */
INTC   IntcInstancePtr;
XPlIrq PlIrqInstancePtr;


static unsigned long g_read_period;
int g_intr0count;


/************************** Function Prototypes *****************************/
static int  SetupIntrSystem(INTC *IntcInstancePtr, XPlIrq *PeriphInstancePtr, u16 IntrId);
static void PlIntrHandler(void *CallBackRef);


#define sev() __asm__("sev")
#define CPU1STARTADR 0xFFFFFFF0
#define CPU1STARTMEM 0x20000000
void StartCpu1(void)
{
    Xil_Out32(CPU1STARTADR, CPU1STARTMEM);
    dmb(); //waits until write has finished
    sev();

    printf("CPU0 启动 CPU1\r\n");
}



/*****************************************************************************/
/*
 *   main()
 */
/******************************************************************************/
int main()
{
	int Status;

	init_platform();

	printf("CPU0 : start\r\n");

    //StartCpu1();

	g_intr0count = 0;


    PlIrqInstancePtr.Config.DeviceId = PL_IRQ_ID;
	PlIrqInstancePtr.Config.BaseAddress = IRQ_PCORE_GEN_BASE;
	PlIrqInstancePtr.IsReady = XIL_COMPONENT_IS_READY;
	PlIrqInstancePtr.IsStarted = 0;
	printf("PL_IRQ_ID : %d\r\n", PL_IRQ_ID);

	/* Connect the PL IRQ to the interrupt subsystem so that interrupts can occur*/
	/* 将PL IRQ连接到中断子系统,以便可能发生中断 */
	Status = SetupIntrSystem(&IntcInstancePtr,&PlIrqInstancePtr,PL_IRQ_ID);
	if (Status != XST_SUCCESS)
	{
		return XST_FAILURE;
	}

	//Xil_Out32(0x40000300, 0xffffffff);


    while(1)
    {
		print("CPU0 main() while(1): Hello World\n\r");

		sleep(1);
    }

    printf("CPU0 : end\r\n");

    cleanup_platform();

    return 0;
}



static int SetupIntrSystem(INTC *IntcInstancePtr,
		XPlIrq *PeriphInstancePtr, u16 IntrId)
{
	int Status;
	XScuGic_Config *IntcConfig;

	/* Initialize the interrupt controller driver so that it is ready to use. */
	/* 初始化中断控制器驱动程序,以使其可以使用。 */
	IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
	if (NULL == IntcConfig) {
		return XST_FAILURE;
	}

	Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,
					IntcConfig->CpuBaseAddress);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	/* Connect the interrupt handler that will be called when an interrupt occurs for the device. */
	/* 连接将在设备发生中断时调用的中断处理程序。 */
	Status = XScuGic_Connect(IntcInstancePtr, IntrId,
				 (Xil_ExceptionHandler)PlIntrHandler,
				 PeriphInstancePtr);

	if (Status != XST_SUCCESS) {
		return Status;
	}

	/* Enable the interrupt for the PL device. 启用PL设备的中断。 */
	XScuGic_Enable(IntcInstancePtr, IntrId);

	/* Initialize the  exception table 初始化异常表 */
	Xil_ExceptionInit();

	/* Register the interrupt controller handler with the exception table */
	/* 用异常表注册中断控制器处理程序 */
	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
			 (Xil_ExceptionHandler)INTC_HANDLER,
			 IntcInstancePtr);

	/* Enable non-critical exceptions 启用非关键性例外 */
	Xil_ExceptionEnable();


	return XST_SUCCESS;
}


static void PlIntrHandler(void *CallBackRef)
{
	XPlIrq *InstancePtr = (XPlIrq *)CallBackRef;

	//XTime time_start=0;
	//XTime time_end=0;
//#define IRTCOUNT (*(volatile unsigned long*)(0x4000012c))
//#define IRTCOUNT1 (*(volatile unsigned long*)(0x40000130))
	/*
	 * Clear the interrupt source
	 */
	//Xil_Out32(InstancePtr->Config.BaseAddress, 10);
	//Xil_Out32(0xf8f01280, 0xFFFFFFFF);
	g_intr0count++;
	//XTime_GetTime(&time_start);
	//IRTCOUNT = 0x0DF;
	//IRTCOUNT1 = g_intr0count;

	//XTime_GetTime(&time_end);
	//g_read_period = (time_end)-(time_start);

	printf("CPU0 PlIntrHandler() :%d \r\n", g_intr0count);
}

发表评论

电子邮件地址不会被公开。 必填项已用*标注