• ZYNQ 7020学习笔记之PL侧普通信号中断PS的实验


    1、参考
    UG585
    网络笔记
    2、理论知识
    见中断部分

    3、实验目的
    练习使用PL侧的普通信号来中断PS处理器。

    4、实验过程
    建立工程,设置并初始化串口中断,在运行程序之后,如果串口接收到N(1-63)个字节数据,则产生串口中断,Zynq响应中断,将数据从RXFIFO读出之后写入到DDR3预定的地址中。

    5、实验平台
    Microphase ZUS zynq7020 开发板。 串口使用 uart1[48,49]. DDR选择 MT41J256M16 RE-125,32bit. BANK1 = 1.8v.

    6、Vivado 建立工程
    block design 如下:
    在这里插入图片描述

    7、SDK的工程程序

    /******************************************************************************
    *
    * Copyright (C) 2009 - 2014 Xilinx, Inc.  All rights reserved.
    *
    * Permission is hereby granted, free of charge, to any person obtaining a copy
    * of this software and associated documentation files (the "Software"), to deal
    * in the Software without restriction, including without limitation the rights
    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    * copies of the Software, and to permit persons to whom the Software is
    * furnished to do so, subject to the following conditions:
    *
    * The above copyright notice and this permission notice shall be included in
    * all copies or substantial portions of the Software.
    *
    * Use of the Software is limited solely to applications:
    * (a) running on a Xilinx device, or
    * (b) that interact with a Xilinx device through a bus or interconnect.
    *
    * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
    * XILINX  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
    * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
    * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    * SOFTWARE.
    *
    * Except as contained in this notice, the name of the Xilinx shall not be used
    * in advertising or otherwise to promote the sale, use or other dealings in
    * this Software without prior written authorization from Xilinx.
    *
    ******************************************************************************/
    
    #include <stdio.h>
    #include "platform.h"
    #include "xil_printf.h"
    #include "xscugic.h"
    #include "xscutimer.h"
    #include "xparameters.h"
    #include "xil_exception.h"
    
    #include <unistd.h>  //sleep()  usleep()
    
    #define 	INTC_DEVICE_ID		 		XPAR_PS7_SCUGIC_0_DEVICE_ID
    #define		INTC_PL_INTERRUPT_ID 	   	XPAR_FABRIC_MY_AXI4LITE_IP_0_PL_TO_ZYNQ_IRQ_INTR
    #define		INT_TYPE_MASK				0x01
    #define     INT_TYPE_RISING_EDGE        0X03
    #define     INT_TYPE_HIGHLEVEL 			0X01
    #define 	INT_CFG0_OFFSET 			0x00000C00  //(intID/16 )*4
    #define 	INT_ENABLE_OFFSET 			0x00000100  //(intID/32 )*4
    #define 	INT_CLEAR_OFFSET 			0x00000280  //(intID/32 )*4
    #define 	INT_PRIORITY_OFFSET 		0x00000400  //(intID/4 )*4
    #define 	INT_PROCESSORTARGET_OFFSET 	0x00000800  //(intID/4 )*4
    
    #define 	INT_ICCPMR_OFFSET 	0xF8F00104
    #define 	INT_ICCICR_OFFSET 	0xF8F00100
    
    
    #define     BRAM_BASS_ADDRESS    0X40000000
    
    XScuGic		INTCInst;
    
    static	void	PLIRQIntrHandler(void	*	InstancePtr);  //中断处理功能函数
    static  void 	CPU_Init(void);
    static  void 	IntcTypeSetup(XScuGic *InstancePtr, int intId, int intType) ;
    static  void 	IntcTypeEnable(XScuGic *InstancePtr, int intId, int intMask) ;
    static  void 	IntcTypeClear(XScuGic *InstancePtr, int intId ) ;
    static	int		InterruptSystemSetup(XScuGic	* XScuGicInstancePtr);   //中断系统建立
    static  int		IntcInitFunction(u16 DeviceID);  //中断控制器初始化功能
    
    int main()
    {
        init_platform();
        CPU_Init();
    
        int status;
    
        //中断建立
         status = IntcInitFunction(INTC_DEVICE_ID);
         if(status != XST_SUCCESS)
        	 return		XST_FAILURE ;
    
        print(">>>>>>>>>>>> TEST Start >>>>>>>>>>>>>>>>
    
    ");
        print(" Press the Key for PL begin write data to PS DDR3 : 
    
    ");
        while(1)
        {
    
        	;
        }
    
    
        cleanup_platform();
        return 0;
    }
    
    
    // 中断控制器初始化功能
    static int IntcInitFunction(u16 DeviceId)
    {
    	XScuGic_Config	* IntcConfig ;
    	int		status;
    
    	printf("Enter the interrupt system >>>>>>
    ");
    	// 第二步, 对中断控制器进行初始化
    	IntcConfig = XScuGic_LookupConfig(DeviceId);   //查找 GIC 的ID
    	status = XScuGic_CfgInitialize(&INTCInst, IntcConfig, IntcConfig->CpuBaseAddress);
    	if(status != XST_SUCCESS)
    		return XST_FAILURE;
    
    	//第三步,建立中断系统
    	status = InterruptSystemSetup(&INTCInst);
    	if(status != XST_SUCCESS)
    		return	XST_FAILURE ;
    
    	//第四步,GPIO中断连接到GIC上
    	status = XScuGic_Connect(&INTCInst, INTC_PL_INTERRUPT_ID,
    			(Xil_ExceptionHandler)PLIRQIntrHandler, (void *)1);
    
    	if(status != XST_SUCCESS)
    			return	XST_FAILURE ;
    
      //******************//
    	// 参考
        IntcTypeSetup(&INTCInst,  INTC_PL_INTERRUPT_ID, INT_TYPE_RISING_EDGE);   //重要
        IntcTypeEnable(&INTCInst,  INTC_PL_INTERRUPT_ID, INT_TYPE_MASK);
    
    //*********************************//
    	XScuGic_Enable(&INTCInst, INTC_PL_INTERRUPT_ID); //CIG允许中断
    
    	return XST_SUCCESS ;
    }
    
    
    static int InterruptSystemSetup (XScuGic * XScuGicInstancePtr)
    {
    	//中断异常的处理,指定该中断异常的处理器
    	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
    			(Xil_ExceptionHandler)XScuGic_InterruptHandler, XScuGicInstancePtr);
    
    	Xil_ExceptionEnable();   //异常处理使能
    
    	return XST_SUCCESS;
    
    
    }
    
    
    void IntcTypeSetup(XScuGic *InstancePtr, int intId, int intType)
    {
      //Setup 包括 触发方式配置, 优先级配置,CPU连接。 设置某个中断信息的前提是不影响其他中断设置
        int mask;
    
       //设置边沿触发方式
        mask = XScuGic_DistReadReg(InstancePtr, INT_CFG0_OFFSET + (intId/16)*4);     //read ICDICFR  *4,因为1个寄存器4个字节
        mask &= ~(0X3 << (intId%16)*2);  		//把读出的值对应2bit,清00,其他保持不变             //*2因为每个中断对应2bit
        mask |= intType << ((intId%16)*2);         	//把清0后的值对应2bit,写01,其他保持不变
        XScuGic_DistWriteReg(InstancePtr, INT_CFG0_OFFSET + (intId/16)*4, mask);     //WRITE ICDICFR
    
        //设置优先级
        mask = XScuGic_DistReadReg(InstancePtr, INT_PRIORITY_OFFSET + (intId/4)*4);     //read 优先级状态
    	mask &= ~(0XFE << (intId%4)*8);        //把读出的值对应8bit,清00,其他保持不变             //*8因为每个中断对应8bit
    	mask |= 0XA0 << ((intId%4)*8);         //把清0后的值对应8bit,写A0,其他保持不变
    	XScuGic_DistWriteReg(InstancePtr, INT_PRIORITY_OFFSET + (intId/4)*4, mask);     //WRITE ICDICFR
    
        //设置处理器CPIID
    	mask = XScuGic_DistReadReg(InstancePtr, INT_PROCESSORTARGET_OFFSET + (intId/4)*4);     //read 优先级状态
    	mask &= ~(0X03 << (intId%4)*8);        //把读出的值对应8bit,清00,其他保持不变             //*8因为每个中断对应8bit
    	mask |= 0X01 << ((intId%4)*8);         //把清0后的值对应8bit,写A0,其他保持不变
    	XScuGic_DistWriteReg(InstancePtr, INT_PROCESSORTARGET_OFFSET + (intId/4)*4, mask);     //WRITE ICDICFR
    
    }
    
    void IntcTypeEnable(XScuGic *InstancePtr, int intId,int intMask)
    {
      // 本函数 只包括 使能中断。使能之前先判断是否需要屏蔽
        int mask;
    
        mask = XScuGic_DistReadReg(InstancePtr, INT_ENABLE_OFFSET + (intId/32)*4);
        mask &= ~(0x01 << (intId%32)*1);   //把对应的Enable bit 清0
        mask |= intMask << ((intId%32)*1); //把对应的Enable bit 与 mask
        XScuGic_DistWriteReg(InstancePtr, INT_ENABLE_OFFSET + (intId/32)*4, mask);     //WRITE ICDICFR
    }
    
    void IntcTypeClear(XScuGic *InstancePtr, int intId )
    {
    	//本函数仅包括清楚中断,注意只能清除本中断对应的寄存器位
    	 int mask;
    
        mask = XScuGic_DistReadReg(InstancePtr, INT_CLEAR_OFFSET + (intId/32)*4);     //read  ICDICPR
        mask &= ~(0x01 << (intId%32)*1);
        mask |= 0x01 << ((intId%32)*1);
        XScuGic_DistWriteReg(InstancePtr, INT_CLEAR_OFFSET + (intId/32)*4, mask);     //WRITE  ICDICPR
    }
    
    
    
    void CPU_Init( )
    {
        //中断优先级都是A0,优先级高于F0,CPU可接受这些中断
    	Xil_Out32(INT_ICCPMR_OFFSET,0xF0);
        //处理器能接收IRQ,使能中断信号连接到处理器
    	Xil_Out32(INT_ICCICR_OFFSET,0x07);
    }
    
    
    static void PLIRQIntrHandler(void * InstancePtr)
    {
    	//default led all turn off
    	printf("
    ************* test STARAT *********************
    ");
        int i;
        int readdata;
    	sleep(1);
    
    	for(i = 0; i < 4; i++)
    	{
    		readdata = Xil_In32(BRAM_BASS_ADDRESS+i*4);              //读取数据函数。
    		sleep(1);
    		printf("the read address is 0x%04x, the read data is 0x%04x.
    ", BRAM_BASS_ADDRESS+i*4, readdata);
    	}
    
    	printf("
    ************* test finish *********************
    ");
    	// ***************************************************** //
    
    	IntcTypeClear(&INTCInst,  INTC_PL_INTERRUPT_ID);
    	IntcTypeEnable(&INTCInst,  INTC_PL_INTERRUPT_ID, INT_TYPE_MASK);
    
    }
    
    

    8 调试结果

    在这里插入图片描述

  • 相关阅读:
    浅析8种常用排序
    尾递归和线性递归
    线性表之顺序表
    安装minikube
    error while loading shared libraries: libatomic.so.1: cannot open shared object file: No such file or directory
    fatal error: 'openssl/conf.h' file not found
    GraphQL 最突出的架构优势是什么?
    mac 安装 brew
    Clean Architecture
    sql优化
  • 原文地址:https://www.cnblogs.com/fhyfhy/p/11760986.html
Copyright © 2020-2023  润新知