UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Voyager
Voyager
10,311 Views
Registered: ‎02-10-2012

PL-PS Interrupt for Zynq running FreeRTOS

Jump to solution

Hey

 

Has any one successfully been able to connect the Zynq PL interrupt to the PS running the FreeRTOS OS ? All the documentation and search results related to Zynq PL-PS Interrupts seem to throw up results related to Stand Alone BSP based applications.

 

Any pointers to good documentation that I may have missed will be super usefull :)

 

Thanks


Regards

Arvind 

Tags (2)
0 Kudos
1 Solution

Accepted Solutions
Voyager
Voyager
14,807 Views
Registered: ‎02-10-2012

Re: PL-PS Interrupt for Zynq running FreeRTOS

Jump to solution

Hey

 

So I was able to figure it out and I have placed what I did below as a reference for any who might have the same problem .

 

My main reference was this : http://forums.xilinx.com/t5/Xcell-Daily-Blog/Adam-Taylor-s-MicroZed-Chronicles-Part-38-Answering-a-question/ba-p/479978

 

I think the blog is wonderful with a lot of useful information.


Initialise the interrupt the following way

 

#define ZYNQ_GPIO_INTERRUPT_PIN 54
#define GPIO_INTERRUPT_ID XPS_GPIO_INT_ID

 

 

void fpga_gpio_fabric_interrupt_init(){

    XGpioPs_Config *GPIOConfigPtr; //GPIO Configuration Pointer
    XGpioPs *GpioP; //GPIO Instance Pointer
    GpioP = &GpioI;

 
    GPIOConfigPtr = XGpioPs_LookupConfig(XPAR_XGPIOPS_0_DEVICE_ID);
    XGpioPs_CfgInitialize(&GpioI, GPIOConfigPtr,GPIOConfigPtr->BaseAddr);
    XGpioPs_SetDirectionPin(&GpioI, ZYNQ_GPIO_INTERRUPT_PIN, 0);

    /* Get interrupt controller instance pointer from FreeRTOS */
    GicInstancePtr = (XScuGic*)prvGetInterruptControllerInstance();

    /* Connect the Zynq GPIO interrupt controller to the FreeRTOS interrupts */
    XScuGic_Connect(GicInstancePtr, GPIO_INTERRUPT_ID,
                    (Xil_ExceptionHandler)XGpioPs_IntrHandler,
                    (void *)GpioP);


    /* Assign interrupt properties to the particular Inbuilt Zynq GPIO controller pin */
    XGpioPs_SetIntrTypePin(GpioP, ZYNQ_GPIO_INTERRUPT_PIN, XGPIOPS_IRQ_TYPE_EDGE_RISING);

    /* Assign the Callback function to call once the interrupt occurs */
    XGpioPs_SetCallbackHandler(GpioP, (void *)GpioP, (void *)GPIOIntrHandler);

    /* Enable the interrupts on the particular Inbuilt Zynq GPIO controller Pin */
    XGpioPs_IntrEnablePin(GpioP, ZYNQ_GPIO_INTERRUPT_PIN);

    /* Enable the interrupts for the Zynq GPIO controller */
    XScuGic_Enable(GicInstancePtr, GPIO_INTERRUPT_ID);
}

 

static void GPIOIntrHandler(void *CallBackRef){

 

    XGpioPs *Gpioint = (XGpioPs *)CallBackRef;
    intrrupt_count ++;
    XGpioPs_IntrClearPin(Gpioint, ZYNQ_GPIO_INTERRUPT_PIN);
}

 

Call the fpga_gpio_fabric_interrupt_init() from the

 

vApplicationSetupHardware() function.

 

Works okay.

 

Regards

Arvind

 

 

 

View solution in original post

0 Kudos
7 Replies
Voyager
Voyager
14,808 Views
Registered: ‎02-10-2012

Re: PL-PS Interrupt for Zynq running FreeRTOS

Jump to solution

Hey

 

So I was able to figure it out and I have placed what I did below as a reference for any who might have the same problem .

 

My main reference was this : http://forums.xilinx.com/t5/Xcell-Daily-Blog/Adam-Taylor-s-MicroZed-Chronicles-Part-38-Answering-a-question/ba-p/479978

 

I think the blog is wonderful with a lot of useful information.


Initialise the interrupt the following way

 

#define ZYNQ_GPIO_INTERRUPT_PIN 54
#define GPIO_INTERRUPT_ID XPS_GPIO_INT_ID

 

 

void fpga_gpio_fabric_interrupt_init(){

    XGpioPs_Config *GPIOConfigPtr; //GPIO Configuration Pointer
    XGpioPs *GpioP; //GPIO Instance Pointer
    GpioP = &GpioI;

 
    GPIOConfigPtr = XGpioPs_LookupConfig(XPAR_XGPIOPS_0_DEVICE_ID);
    XGpioPs_CfgInitialize(&GpioI, GPIOConfigPtr,GPIOConfigPtr->BaseAddr);
    XGpioPs_SetDirectionPin(&GpioI, ZYNQ_GPIO_INTERRUPT_PIN, 0);

    /* Get interrupt controller instance pointer from FreeRTOS */
    GicInstancePtr = (XScuGic*)prvGetInterruptControllerInstance();

    /* Connect the Zynq GPIO interrupt controller to the FreeRTOS interrupts */
    XScuGic_Connect(GicInstancePtr, GPIO_INTERRUPT_ID,
                    (Xil_ExceptionHandler)XGpioPs_IntrHandler,
                    (void *)GpioP);


    /* Assign interrupt properties to the particular Inbuilt Zynq GPIO controller pin */
    XGpioPs_SetIntrTypePin(GpioP, ZYNQ_GPIO_INTERRUPT_PIN, XGPIOPS_IRQ_TYPE_EDGE_RISING);

    /* Assign the Callback function to call once the interrupt occurs */
    XGpioPs_SetCallbackHandler(GpioP, (void *)GpioP, (void *)GPIOIntrHandler);

    /* Enable the interrupts on the particular Inbuilt Zynq GPIO controller Pin */
    XGpioPs_IntrEnablePin(GpioP, ZYNQ_GPIO_INTERRUPT_PIN);

    /* Enable the interrupts for the Zynq GPIO controller */
    XScuGic_Enable(GicInstancePtr, GPIO_INTERRUPT_ID);
}

 

static void GPIOIntrHandler(void *CallBackRef){

 

    XGpioPs *Gpioint = (XGpioPs *)CallBackRef;
    intrrupt_count ++;
    XGpioPs_IntrClearPin(Gpioint, ZYNQ_GPIO_INTERRUPT_PIN);
}

 

Call the fpga_gpio_fabric_interrupt_init() from the

 

vApplicationSetupHardware() function.

 

Works okay.

 

Regards

Arvind

 

 

 

View solution in original post

0 Kudos
Visitor hkyhow12
Visitor
8,172 Views
Registered: ‎07-22-2016

Re: PL-PS Interrupt for Zynq running FreeRTOS

Jump to solution

When I type in  (XScuGic*)prvGetInterruptControllerInstance();

the compiler said it is not found. Which header file did you include to call the function?

 

Thank you!

0 Kudos
Visitor alberto444
Visitor
7,997 Views
Registered: ‎05-05-2016

Re: PL-PS Interrupt for Zynq running FreeRTOS

Jump to solution

Hi, did you use the sample application that you can generate from within the Xilinx SDK or some demo project (like "blinky") directly from the FreeRTOS website?

0 Kudos
Contributor
Contributor
6,810 Views
Registered: ‎03-11-2016

Re: PL-PS Interrupt for Zynq running FreeRTOS

Jump to solution
extern XScuGic xInterruptController;
//Connect to the hardware
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler,&xInterruptController);
//Trigger Rising Edge
XScuGic_SetPriorityTriggerType(&xInterruptController, 61, 4, 3);
XScuGic_Connect(&xInterruptController, 61, (Xil_ExceptionHandler) DMA_complete_handle, (void *)&xInterruptController);
//Enable PL-PS INTR Pin 61
XScuGic_Enable(&xInterruptController, 61);

The above works on 8.2.3 BSP

XScuGic xInterruptController;

is defined in the portZynq7000.c

0 Kudos
Visitor fastian12
Visitor
6,004 Views
Registered: ‎07-20-2017

Re: PL-PS Interrupt for Zynq running FreeRTOS

Jump to solution

Hy..Currently I am working on FreeRTOS CORTEX A9 port. I am using ZEDBOARD (Evaluation Card). I want to use PS-MIO pin as interrupt. I am facing some issues here.

1) When an interrupt occur on MIO-Pin, GPIO Interrupt Handler Function Calls two times.

2) Also, another issue is that when an interrupt occurs, corresponding bit is set in GPIO Status Register. But when I clears it flag GPIO Status Register, it does not clear.

3) At start, GPIO status register shows some unknown value. So I have to reset it manually.

 

 Kindly check what is the problem in the code. My complete code is attached here. Thanks..

 

////CODE

 

/* Standard includes. */
#include <stdio.h>
#include <limits.h>

/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"

/* Standard demo includes. */
#include "partest.h"
#include "TimerDemo.h"
#include "QueueOverwrite.h"
#include "EventGroupsDemo.h"
#include "TaskNotify.h"
#include "IntSemTest.h"

/* Xilinx includes. */
#include "platform.h"
#include "xparameters.h"
#include "xscutimer.h"
#include "xscugic.h"
#include "xil_exception.h"
#include "timers.h"

#include "xgpiops.h"

 


extern void vPortInstallFreeRTOSVectorTable( void );

/* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. */
void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );
void vApplicationTickHook( void );


/* The private watchdog is used as the timer that generates run time
stats. This frequency means it will overflow quite quickly. */
XScuWdt xWatchDogInstance;

/*-----------------------------------------------------------*/

/* The interrupt controller is initialised in this file, and made available to
other modules. */
XScuGic xInterruptController;

/*-----------------------------------------------------------*/
XGpioPs xGpio;
void check_gpio_interrupt_status_reg();
static void vPeriodicTask( void *pvParameters );
static void prvSetupHardware( void );
void GPIOIntrHandler(void *CallBackRef);
void fpga_gpio_fabric_interrupt_init();


#define ZYNQ_GPIO_INTERRUPT_PIN 13
#define GPIO_INTERRUPT_ID XPS_GPIO_INT_ID


int main( void )
{


check_gpio_interrupt_status_reg();

prvSetupHardware();

xTaskCreate( vPeriodicTask, "Periodic", 1000, NULL, 1, NULL );

vTaskStartScheduler();

return 0;
}

 

static void vPeriodicTask( void *pvParameters )
{
const TickType_t xDelay500ms = pdMS_TO_TICKS( 500UL );
/* As per most tasks, this task is implemented within an infinite loop. */
volatile uint32_t ul;

for( ;; )
{
/* Block until it is time to generate the software interrupt again. */
//vTaskDelay( xDelay500ms );
for( ul = 0; ul < 50000000; ul++ )
{

}
xil_printf( "Periodic task Running..\r\n" );

}
}

 


static void prvSetupHardware( void )
{

portDISABLE_INTERRUPTS();

fpga_gpio_fabric_interrupt_init();

vPortInstallFreeRTOSVectorTable();

}

void check_gpio_interrupt_status_reg()
{

uint32_t Data1 = XGpioPs_ReadReg(0xe000a000, 0x00000218);

uint32_t *check_addr1;

check_addr1 = 0xe000a000 + 0x00000218;

xil_printf("Data at Status Register before initialization : %X is %X \r\n", check_addr1, Data1);

if(Data1 != 0)
{
Data1 = 0xFFFFFFFF;

XGpioPs_WriteReg(0xe000a000, 0x00000218, Data1);

Data1 = XGpioPs_ReadReg(0xe000a000, 0x00000218);

xil_printf("Data at Status Register after initialization : %X is %X \r\n", check_addr1, Data1);

}


}


void fpga_gpio_fabric_interrupt_init()
{

XScuGic_Config *pxGICConfig;
BaseType_t xStatus;


uint32_t *check_addr2;
check_addr2 = 0xE000A000 + 0x0000020C;
xil_printf("Data at Mask Register Before Interrupt Declaration : %X is %X \r\n", check_addr2, *check_addr2);


pxGICConfig = XScuGic_LookupConfig( XPAR_SCUGIC_SINGLE_DEVICE_ID );

configASSERT( pxGICConfig );
configASSERT( pxGICConfig->CpuBaseAddress == ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET ) );
configASSERT( pxGICConfig->DistBaseAddress == configINTERRUPT_CONTROLLER_BASE_ADDRESS );

xStatus = XScuGic_CfgInitialize( &xInterruptController, pxGICConfig, pxGICConfig->CpuBaseAddress );
configASSERT( xStatus == XST_SUCCESS );
( void ) xStatus;

 

XGpioPs_Config *pxConfigPtr;
BaseType_t xStatus1;

pxConfigPtr = XGpioPs_LookupConfig(XPAR_XGPIOPS_0_DEVICE_ID);
xStatus1 = XGpioPs_CfgInitialize(&xGpio, pxConfigPtr,pxConfigPtr->BaseAddr);
configASSERT( xStatus1 == XST_SUCCESS );
( void ) xStatus1;


XGpioPs_SetDirectionPin(&xGpio, ZYNQ_GPIO_INTERRUPT_PIN, 0);


XScuGic_Connect(&xInterruptController, GPIO_INTERRUPT_ID,
(Xil_ExceptionHandler)XGpioPs_IntrHandler,
&xGpio);

 


XGpioPs_SetIntrTypePin(&xGpio, ZYNQ_GPIO_INTERRUPT_PIN, XGPIOPS_IRQ_TYPE_LEVEL_LOW);

 

XGpioPs_SetCallbackHandler(&xGpio, (void *)&xGpio, (void *)GPIOIntrHandler);

xil_printf("Declaration Function is called \r\n");

XGpioPs_IntrEnablePin(&xGpio, ZYNQ_GPIO_INTERRUPT_PIN);

XScuGic_Enable(&xInterruptController, GPIO_INTERRUPT_ID);

xil_printf("Data at Mask Register after Interrupt Declaration : %X is %X \r\n", check_addr2, *check_addr2);


}


void GPIOIntrHandler(void *CallBackRef)
{


uint32_t *check_addr3;
check_addr3 = 0xE000A000 + 0x00000218;
xil_printf("Data at Status Register after Interrupt Occurs : %X is %X \r\n", check_addr3, *check_addr3);

 

uint32_t Data = 0xFFFFFFFF;
*check_addr3 = Data;

xil_printf("Data at Status Register after Interrupt Clear : %X is %X \r\n", check_addr3, *check_addr3);

 

uint32_t *check_addr4;
check_addr4 = 0xE000A000 + 0x00000214;
*check_addr4 = Data;

xil_printf("Interrupt has been disabled \r\n");

 

}

 

 

 

 

/*-----------------------------------------------------------*/

void vApplicationMallocFailedHook( void )
{
/* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
taskDISABLE_INTERRUPTS();
for( ;; );
}
/*-----------------------------------------------------------*/

void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;

/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS();
for( ;; );
}
/*-----------------------------------------------------------*/

void vApplicationIdleHook( void )
{
volatile size_t xFreeHeapSpace, xMinimumEverFreeHeapSpace;

/* This is just a trivial example of an idle hook. It is called on each
cycle of the idle task. It must *NOT* attempt to block. In this case the
idle task just queries the amount of FreeRTOS heap that remains. See the
memory management section on the http://www.FreeRTOS.org web site for memory
management options. If there is a lot of heap memory free then the
configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
RAM. */
xFreeHeapSpace = xPortGetFreeHeapSize();
xMinimumEverFreeHeapSpace = xPortGetMinimumEverFreeHeapSize();

/* Remove compiler warning about xFreeHeapSpace being set but never used. */
( void ) xFreeHeapSpace;
( void ) xMinimumEverFreeHeapSpace;
}
/*-----------------------------------------------------------*/

void vAssertCalled( const char * pcFile, unsigned long ulLine )
{
volatile unsigned long ul = 0;

( void ) pcFile;
( void ) ulLine;

taskENTER_CRITICAL();
{
/* Set ul to a non-zero value using the debugger to step out of this
function. */
while( ul == 0 )
{
portNOP();
}
}
taskEXIT_CRITICAL();
}
/*-----------------------------------------------------------*/

void vApplicationTickHook( void )
{
#if( mainSELECTED_APPLICATION == 1 )
{
/* The full demo includes a software timer demo/test that requires
prodding periodically from the tick interrupt. */
vTimerPeriodicISRTests();

/* Call the periodic queue overwrite from ISR demo. */
vQueueOverwritePeriodicISRDemo();

/* Call the periodic event group from ISR demo. */
vPeriodicEventGroupsProcessing();

/* Use task notifications from an interrupt. */
xNotifyTaskFromISR();

/* Use mutexes from interrupts. */
vInterruptSemaphorePeriodicTest();
}
#endif
}
/*-----------------------------------------------------------*/

void *memcpy( void *pvDest, const void *pvSource, size_t xBytes )
{
/* The compiler used during development seems to err unless these volatiles are
included at -O3 optimisation. */
volatile unsigned char *pcDest = ( volatile unsigned char * ) pvDest, *pcSource = ( volatile unsigned char * ) pvSource;
size_t x;

/* Extremely crude standard library implementations in lieu of having a C
library. */
if( pvDest != pvSource )
{
for( x = 0; x < xBytes; x++ )
{
pcDest[ x ] = pcSource[ x ];
}
}

return pvDest;
}
/*-----------------------------------------------------------*/

void *memset( void *pvDest, int iValue, size_t xBytes )
{
/* The compiler used during development seems to err unless these volatiles are
included at -O3 optimisation. */
volatile unsigned char * volatile pcDest = ( volatile unsigned char * volatile ) pvDest;
volatile size_t x;

/* Extremely crude standard library implementations in lieu of having a C
library. */
for( x = 0; x < xBytes; x++ )
{
pcDest[ x ] = ( unsigned char ) iValue;
}

return pvDest;
}
/*-----------------------------------------------------------*/

int memcmp( const void *pvMem1, const void *pvMem2, size_t xBytes )
{
const volatile unsigned char *pucMem1 = pvMem1, *pucMem2 = pvMem2;
volatile size_t x;

/* Extremely crude standard library implementations in lieu of having a C
library. */
for( x = 0; x < xBytes; x++ )
{
if( pucMem1[ x ] != pucMem2[ x ] )
{
break;
}
}

return xBytes - x;
}
/*-----------------------------------------------------------*/

void vInitialiseTimerForRunTimeStats( void )
{
XScuWdt_Config *pxWatchDogInstance;
uint32_t ulValue;
const uint32_t ulMaxDivisor = 0xff, ulDivisorShift = 0x08;

pxWatchDogInstance = XScuWdt_LookupConfig( XPAR_SCUWDT_0_DEVICE_ID );
XScuWdt_CfgInitialize( &xWatchDogInstance, pxWatchDogInstance, pxWatchDogInstance->BaseAddr );

ulValue = XScuWdt_GetControlReg( &xWatchDogInstance );
ulValue |= ulMaxDivisor << ulDivisorShift;
XScuWdt_SetControlReg( &xWatchDogInstance, ulValue );

XScuWdt_LoadWdt( &xWatchDogInstance, UINT_MAX );
XScuWdt_SetTimerMode( &xWatchDogInstance );
XScuWdt_Start( &xWatchDogInstance );
}
/*-----------------------------------------------------------*/

/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
used by the Idle task. */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )
{
/* If the buffers to be provided to the Idle task are declared inside this
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];

/* Pass out a pointer to the StaticTask_t structure in which the Idle task's
state will be stored. */
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB;

/* Pass out the array that will be used as the Idle task's stack. */
*ppxIdleTaskStackBuffer = uxIdleTaskStack;

/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}
/*-----------------------------------------------------------*/

/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
application must provide an implementation of vApplicationGetTimerTaskMemory()
to provide the memory that is used by the Timer service task. */
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize )
{
/* If the buffers to be provided to the Timer task are declared inside this
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB;
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];

/* Pass out a pointer to the StaticTask_t structure in which the Timer
task's state will be stored. */
*ppxTimerTaskTCBBuffer = &xTimerTaskTCB;

/* Pass out the array that will be used as the Timer task's stack. */
*ppxTimerTaskStackBuffer = uxTimerTaskStack;

/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
}

 

 

 

 

 

 

0 Kudos
Visitor fastian12
Visitor
5,999 Views
Registered: ‎07-20-2017

Re: PL-PS Interrupt for Zynq running FreeRTOS

Jump to solution

Kindly first check whether GPIO Interrupt Configuration is done properly or not..

Here is the code of GPIO configuration..

 

 

XScuGic_Config *pxGICConfig;
BaseType_t xStatus;


pxGICConfig = XScuGic_LookupConfig( XPAR_SCUGIC_SINGLE_DEVICE_ID );

configASSERT( pxGICConfig );
configASSERT( pxGICConfig->CpuBaseAddress == ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET ) );
configASSERT( pxGICConfig->DistBaseAddress == configINTERRUPT_CONTROLLER_BASE_ADDRESS );

xStatus = XScuGic_CfgInitialize( &xInterruptController, pxGICConfig, pxGICConfig->CpuBaseAddress );
configASSERT( xStatus == XST_SUCCESS );
( void ) xStatus;

 

XGpioPs_Config *pxConfigPtr;
BaseType_t xStatus1;

pxConfigPtr = XGpioPs_LookupConfig(XPAR_XGPIOPS_0_DEVICE_ID);
xStatus1 = XGpioPs_CfgInitialize(&xGpio, pxConfigPtr,pxConfigPtr->BaseAddr);
configASSERT( xStatus1 == XST_SUCCESS );
( void ) xStatus1;


XGpioPs_SetDirectionPin(&xGpio, ZYNQ_GPIO_INTERRUPT_PIN, 0);


XScuGic_Connect(&xInterruptController, GPIO_INTERRUPT_ID,
(Xil_ExceptionHandler)XGpioPs_IntrHandler,
&xGpio);

 


XGpioPs_SetIntrTypePin(&xGpio, ZYNQ_GPIO_INTERRUPT_PIN, XGPIOPS_IRQ_TYPE_LEVEL_LOW);

 

XGpioPs_SetCallbackHandler(&xGpio, (void *)&xGpio, (void *)GPIOIntrHandler);

xil_printf("Declaration Function is called \r\n");

XGpioPs_IntrEnablePin(&xGpio, ZYNQ_GPIO_INTERRUPT_PIN);

XScuGic_Enable(&xInterruptController, GPIO_INTERRUPT_ID);

 

0 Kudos
2,651 Views
Registered: ‎02-09-2010

Re: PL-PS Interrupt for Zynq running FreeRTOS

Jump to solution

I have posted a new thread, because I also have the issue that the interrupt function is called twice.

https://forums.xilinx.com/t5/Embedded-Development-Tools/Using-FreeRTOS-PL-PS-interrupt-function-called-twice/td-p/886855

0 Kudos