Microblaze GPIO interrupt

I've hit a brick wall with this. I just can't figure out what I'm doing wrong, or not doing right!

I just want to generate an interrupt when the pushbutton (PB) is pressed. This is the only interrupt so far, but I'm using INTC because I want to expand this soon.

The MHS file has: BEGIN opb_intc PARAMETER INSTANCE = opb_intc_0 PARAMETER HW_VER = 1.00.c PARAMETER C_BASEADDR = 0x41200000 PARAMETER C_HIGHADDR = 0x4120ffff BUS_INTERFACE SOPB = mb_opb PORT Irq = Interrupt PORT Intr = Push_Buttons_1Bit_IP2INTC_Irpt END

BEGIN opb_gpio PARAMETER INSTANCE = Push_Buttons_1Bit PARAMETER HW_VER = 3.01.b PARAMETER C_INTERRUPT_PRESENT = 1 PARAMETER C_GPIO_WIDTH = 1 PARAMETER C_IS_DUAL = 0 PARAMETER C_ALL_INPUTS = 1 PARAMETER C_IS_BIDIR = 0 PARAMETER C_BASEADDR = 0x40040000 PARAMETER C_HIGHADDR = 0x4004ffff BUS_INTERFACE SOPB = mb_opb PORT OPB_Clk = sys_clk_s PORT IP2INTC_Irpt = Push_Buttons_1Bit_IP2INTC_Irpt PORT GPIO_in = fpga_0_Push_Buttons_1Bit_GPIO_in END

BEGIN microblaze (snip) PORT Interrupt = Interrupt (snip) END

This is my code:

microblaze_enable_interrupts(); /* Register the UART interrupt handler in the vector table */ XIntc_RegisterHandler(XPAR_OPB_INTC_0_BASEADDR,XPAR_OPB_INTC_0_PUSH_BUTTONS_1BIT_IP2INTC_IRPT_INTR, (XInterruptHandler)pb_int_handler,(void

*)XPAR_PUSH_BUTTONS_1BIT_BASEADDR); /* Start the interrupt controller */ XIntc_mMasterEnable(XPAR_OPB_INTC_0_BASEADDR); /* Enable PB interrupt requests in the interrupt controller */ XIntc_mEnableIntr(XPAR_OPB_INTC_0_BASEADDR,XPAR_PUSH_BUTTONS_1BIT_IP2INTC_IRPT_MASK); /* Enable PB interrupts */ XGpio_InterruptGlobalEnable(XPAR_PUSH_BUTTONS_1BIT_BASEADDR); XGpio_InterruptEnable(XPAR_PUSH_BUTTONS_1BIT_BASEADDR, XPAR_PUSH_BUTTONS_1BIT_IP2INTC_IRPT_MASK);

/* Wait for interrupts */ while (1){ if (num_interrupts >= 1){ xil_printf("-- Number of interrupts received : %x \n\r", num_interrupts); }

When debugging I can see that the IE bit in the MSR gets set. The code hangs on XGpio_InterruptGlobalEnable(XPAR_PUSH_BUTTONS_1BIT_BASEADDR);

The function in question from xgpio_intr.c:

void XGpio_InterruptGlobalEnable(XGpio *InstancePtr) { XASSERT_VOID(InstancePtr != XNULL); XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); XASSERT_VOID(InstancePtr->InterruptPresent == XTRUE);

XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress + XGPIO_IPIF_OFFSET); }

Any help greatly appreciated.

Reply to
markmcmahon
Loading thread data ...

XIntc_RegisterHandler(XPAR_OPB_INTC_0_BASEADDR,XPAR_OPB_INTC_0_PUSH_BUTTONS_1BIT_IP2INTC_IRPT_INTR,

XIntc_mEnableIntr(XPAR_OPB_INTC_0_BASEADDR,XPAR_PUSH_BUTTONS_1BIT_IP2INTC_IRPT_MASK);

You are confusing the InstancePtr concept of the EDK driver model, with the hardware BASEADDR (which is just the physical address of the peripheral's hardware register set).

Check the various tutorials on using the EDK standalone driver model - there are plenty of examples out there.

Here's one to get started with:

formatting link

Regards,

John

Reply to
John Williams

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.