pynq interrupt the test gpio (emio) interrupts

Platform PYNQ-Z2

Realize the function

Here achieve emio access button button IRQ interrupts with pynq

Hardware EMIO 54 pick btn0, through input, triggers an interrupt # 52, to GIC

Here Insert Picture Description
By SPI, interrupt operation and other cpu registers specified trigger IRQ

Here Insert Picture Description

hardware design

Here Insert Picture Description

A EMIO of GPIO_0_0_tri_io discipline leads to btn0

constraint

set_property -dict { PACKAGE_PIN D19   IOSTANDARD LVCMOS33 } [get_ports { GPIO_0_0_tri_io }]; #IO_L4P_T0_35 Sch=btn[0]

software design



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



#include "xgpiops.h"
#include "xgpiops_hw.h"

#include "XSCUGIC.H"
#include "XSCUGIC_HW.H"

#include "sleep.h"



#define ICCPMR   *(volatile unsigned int *) 0xf8f00104
//printf(" ICCPMR = %0X  @ line = %d \n", ICCPMR ,__LINE__  );
//(__FILE__, __LINE__);

#define GPIO_NO 54

static void GpioHandler(void *CallBackRef, int Bank, u32 Status)
{

	static int  i = 0;

	if (Status ==0 ) return ;
    XGpioPs* pGpioPs=(XGpioPs*)CallBackRef;

    XGpioPs_IntrDisablePin(pGpioPs,GPIO_NO);

    printf("Gpio Handler %d...\n\r",i++);

  //  while (1 == XGpioPs_ReadPin( pGpioPs  ,  GPIO_NO )) ;

    usleep(100*1000);
    XGpioPs_IntrClearPin(pGpioPs,GPIO_NO);
    XGpioPs_IntrEnablePin(pGpioPs,GPIO_NO);



}

int main()

{

    XGpioPs Gpio;

    XGpioPs_Config *ConfigPtr;

    printf(" ICCPMR = %0X  @ line = %d \n", ICCPMR ,__LINE__  );


    ConfigPtr = XGpioPs_LookupConfig(0);
    XGpioPs_CfgInitialize(&Gpio, ConfigPtr, ConfigPtr->BaseAddr);
 //初始化GPIO的输入以及中断。

    XGpioPs_SetDirectionPin(&Gpio,GPIO_NO,0x0);


     XGpioPs_SetIntrTypePin(&Gpio,GPIO_NO,XGPIOPS_IRQ_TYPE_EDGE_RISING);
     XGpioPs_SetCallbackHandler(&Gpio, (void *)&Gpio, GpioHandler);
     XGpioPs_IntrEnablePin(&Gpio,GPIO_NO);


     XScuGic ScuGic;
     XScuGic_Config* pScuGicCfg;
     pScuGicCfg=XScuGic_LookupConfig(XPAR_SCUGIC_SINGLE_DEVICE_ID);
     XScuGic_CfgInitialize(&ScuGic,pScuGicCfg,pScuGicCfg->CpuBaseAddress);

     XScuGic_Connect(&ScuGic, 52,
                    (Xil_ExceptionHandler)XGpioPs_IntrHandler,
                    (void *)&Gpio);

     XScuGic_SetPriorityTriggerType(&ScuGic,52,0xa0,0x01);//优先级阈值f0
     XScuGic_Enable(&ScuGic,52);


     Xil_ExceptionInit();
     Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler,&ScuGic);
     Xil_ExceptionEnable();

    printf("Intr test: \n\r");

    while(1)
    {

    }

}





result

button

Here Insert Picture Description
ICCICR (IC CPU IC REG)->
ICDDC R( UC distributor C REG)->

GPIO interrupt function analysis library

void XGpioPs_SetCallbackHandler(XGpioPs *InstancePtr, void *CallBackRef,
				 XGpioPs_Handler FuncPointer)

 XGpioPs_SetCallbackHandler(&Gpio, (void *)&Gpio, GpioHandler);

XGpioPs_Handler function pointer

Interrupt

Processor speed with the speed of the peripheral hardware devices are often not on a order of magnitude, so if you take the core processor to send a request to the hardware, and then wait for a special way to respond, apparently to reduce core efficiency.

Therefore, up to us to provide a mechanism for hardware kernel again send a signal (active initiative to change the kernel hardware) when needed, this is the break mechanism.

Different devices corresponding to different interrupts, each interrupt through a unique digital identity.
For example, it is different from the keyboard interrupt interrupts from the hard disk, so that the operating system is able to distinguish between interruption and know which hardware devices which generated the interrupt. In this way, the operating system in order to provide different different interrupt interrupt handler.

When it executes a program, if there is another event occurs (such as the user has opened a program) so that by the time you need to interrupt mechanism of a computer system to deal with.

Including hardware interrupt mechanismInterruption meansAnd operating systemInterrupt service routine

Let hardware kernel again signaled when needed.

Early computer system interrupts generated by hardware identification code (identification of the interrupt source, may be used to form the corresponding interrupt service routine entry address or storage address of the first interrupt service routine) is calledInterrupt vectorVariable interrupt address

Interrupt vector table: interrupt the connection between the table number and the type of interrupt source entry address corresponding interrupt handler;

_vector_table:
	B	_boot
	B	Undefined
	B	SVCHandler
	B	PrefetchAbortHandler
	B	DataAbortHandler
	NOP	/* Placeholder for address exception vector*/
	B	IRQHandler
	B	FIQHandler

Interrupt service routine: break the code executed when the transmit interrupt

compilation

IRQHandler:					/* IRQ vector handler */

	stmdb	sp!,{r0-r3,r12,lr}		/* state save from compiled code*/
#if FPU_HARD_FLOAT_ABI_ENABLED
	vpush {d0-d7}
	vpush {d16-d31}
	vmrs r1, FPSCR
	push {r1}
	vmrs r1, FPEXC
	push {r1}
#endif

#ifdef PROFILING
	ldr	r2, =prof_pc
	subs	r3, lr, #0
	str	r3, [r2]
#endif

	bl	IRQInterrupt			/* IRQ vector */

C

/*****************************************************************************/
/**
*
* This is the C level wrapper for the IRQ interrupt called from the vectors.s
* file.
*
* @param	None.
*
* @return	None.
*
* @note		None.
*
******************************************************************************/
void IRQInterrupt(void)
{
	XExc_VectorTable[XIL_EXCEPTION_ID_IRQ_INT].Handler(XExc_VectorTable[
					XIL_EXCEPTION_ID_IRQ_INT].Data);
}

#if !defined (__aarch64__)

Here Insert Picture Description

Here Insert Picture Description

Here Insert Picture Description
Here Insert Picture Description

ref
https://blog.csdn.net/qq_18077275/article/details/89304215?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

zynq break

Sources divided into three categories SPI, PPI, SGI total of 96 interrupt ID number

After a break to run multiple interrupt hander interrupt handler, the following steps

  • STEP 1, the first to jump to the interrupt vector to turn the IRQ service routine. It corresponds to the function

  • STEP 2, there are dozens of ways to generate IRQ (ID No. 96), so we need to know specifically what happened happened IRQ interrupts interrupt number. The corresponding call the appropriate handler if found.

  • STEP 3, which find particular interrupt ID number, corresponding to the steps is to re-process may have to be subdivided
    (for example, to 118, 52 GPIO can generate interrupts to determine the specific one of which). As well as other appropriate process.

Published 452 original articles · won praise 271 · views 730 000 +

Guess you like

Origin blog.csdn.net/qq_35608277/article/details/105073908