/* * Interrupts example * */ #include #include "platform.h" #include "xil_printf.h" #include "xparameters.h" #include "xgpio.h" #include "xtmrctr.h" #include "xscugic.h" /* * Defines for the constants needed in the code * */ #define TIMER_COUNTER_0 0 #define GPIO_CHAN_1 1 #define ASCENDING_MASK 0x1 #define DESCENDING_MASK 0x2 //uncomment ONLY ONE of the options #define OPTION_A //#define OPTION_B /* * Type declarations and global variables * */ typedef struct { XTmrCtr *TimerPtr; XGpio *GpioLedsPtr; } TimerHandlerArg_t; int Step = 0, Ascending = 0, IntFlag = 0; /* * Function prototypes * */ #ifdef OPTION_A static void TimerHandler(void *CallBackRef, u8 TmrCtrNumber); #endif #ifdef OPTION_B static void TimerHandler(void *CallBackRef); #endif static void GpioButtonsHandler(void *CallBackRef); int SetupPeripherals(XGpio *GpioButtonsPtr, XGpio *GpioLedsPtr, XTmrCtr *TimerPtr); /* * Timer ISR * */ #ifdef OPTION_A static void TimerHandler(void *CallBackRef, u8 TmrCtrNumber) { // This variable is not used here, so followed line is commented out //XTmrCtr *TimerPtr = (XTmrCtr *) CallBackRef; IntFlag = 1; } #endif #ifdef OPTION_B static void TimerHandler(void *CallBackReg) { TimerHandlerArg_t *TimerHandlerArgPtr = (TimerHandlerArg_t *) CallBackReg; XTmrCtr *TimerPtr = TimerHandlerArgPtr->TimerPtr; XGpio *GpioLedsPtr = TimerHandlerArgPtr->GpioLedsPtr; uint32_t csr; // Read the control/status register to check interrupt flag bit csr = XTmrCtr_ReadReg(TimerPtr->BaseAddress, TIMER_COUNTER_0, XTC_TCSR_OFFSET); if (csr & XTC_CSR_INT_OCCURED_MASK) { // Interrupt acknowledgement: Clear the timer interrupt csr |= XTC_CSR_INT_OCCURED_MASK; XTmrCtr_WriteReg(TimerPtr->BaseAddress, TIMER_COUNTER_0, XTC_TCSR_OFFSET, csr); // Application specific code if (Ascending) { XGpio_DiscreteWrite(GpioLedsPtr, 1, Step++); if (Step>63) Step=0; } else { XGpio_DiscreteWrite(GpioLedsPtr, 1, Step--); if (Step<0) Step=63; } IntFlag = 0; } } #endif /* * GPIO ISR * */ static void GpioButtonsHandler(void *CallBackRef) { XGpio *GpioButtonsPtr = (XGpio *) CallBackRef; if (XGpio_DiscreteRead(GpioButtonsPtr, GPIO_CHAN_1) & ASCENDING_MASK) Ascending = 1; if (XGpio_DiscreteRead(GpioButtonsPtr, GPIO_CHAN_1) & DESCENDING_MASK) Ascending = 0; XGpio_InterruptClear(GpioButtonsPtr, XGPIO_IR_CH1_MASK); } /* * Function to initialize peripherals * */ int SetupPeripherals(XGpio *GpioButtonsPtr, XGpio *GpioLedsPtr, XTmrCtr *TimerPtr) { int Status; Status = XGpio_Initialize(GpioButtonsPtr, XPAR_GPIO_0_DEVICE_ID); if (Status != XST_SUCCESS) { printf("ERROR: Initialization of buttons GPIO failed \n\r"); return XST_FAILURE; } Status = XGpio_Initialize(GpioLedsPtr, XPAR_GPIO_1_DEVICE_ID); if (Status != XST_SUCCESS) { printf("ERROR: Initialization of LEDs GPIO failed \n\r"); return XST_FAILURE; } Status = XTmrCtr_Initialize(TimerPtr, XPAR_TMRCTR_0_DEVICE_ID); if (Status != XST_SUCCESS) { printf("ERROR: Initialization of Timer failed \n\r"); return XST_FAILURE; } return XST_SUCCESS; } /* * Function to initialize interrupt subsystem * */ #ifdef OPTION_A int SetupInterrupts(XScuGic *GicPtr, XTmrCtr *TimerPtr, XTmrCtr_Handler TimerHandler, XGpio *GpioButtonsPtr, Xil_ExceptionHandler GpioButtonsHandler, TimerHandlerArg_t *TimerHandlerArgPtr) { #endif #ifdef OPTION_B int SetupInterrupts(XScuGic *GicPtr, XTmrCtr *TimerPtr, Xil_ExceptionHandler TimerHandler, XGpio *GpioButtonsPtr, Xil_ExceptionHandler GpioButtonsHandler, TimerHandlerArg_t *TimerHandlerArgPtr) { #endif int Status; XScuGic_Config *GicCfgPtr; // GIC initialization GicCfgPtr = XScuGic_LookupConfig(XPAR_SCUGIC_0_DEVICE_ID); if(GicCfgPtr == NULL) { printf("ERROR: GIC configuration not found \n\r"); return XST_FAILURE; } Status = XScuGic_CfgInitialize(GicPtr, GicCfgPtr, GicCfgPtr->CpuBaseAddress); if (Status != XST_SUCCESS) { printf("ERROR: GIC initialization failed \n\r"); return Status; } // Register timer interrupts #ifdef OPTION_A XTmrCtr_SetHandler(TimerPtr, TimerHandler, TimerPtr); Status = XScuGic_Connect(GicPtr, XPAR_FABRIC_TMRCTR_0_VEC_ID, (Xil_ExceptionHandler) XTmrCtr_InterruptHandler, (void *) TimerPtr); if (Status != XST_SUCCESS) { printf("ERROR: Could not register Timer ISR in GIC \n\r"); return Status; } #endif #ifdef OPTION_B Status = XScuGic_Connect(GicPtr, XPAR_FABRIC_TMRCTR_0_VEC_ID, (Xil_ExceptionHandler) TimerHandler, (void *) TimerHandlerArgPtr); if (Status != XST_SUCCESS) { printf("ERROR: Could not register Timer ISR in GIC \n\r"); return Status; } #endif // Register GPIO interrupts Status = XScuGic_Connect(GicPtr, XPAR_FABRIC_GPIO_0_VEC_ID, (Xil_ExceptionHandler) GpioButtonsHandler, (void *) GpioButtonsPtr); if (Status != XST_SUCCESS) { printf("ERROR: Could not register GPIO ISR in GIC \n\r"); return Status; } // Initialize exception system Xil_ExceptionInit(); Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT, (Xil_ExceptionHandler) XScuGic_InterruptHandler, GicPtr); // Enable interrupts at GIC XScuGic_Enable(GicPtr, XPAR_FABRIC_TMRCTR_0_VEC_ID); XScuGic_Enable(GicPtr, XPAR_FABRIC_GPIO_0_VEC_ID); return XST_SUCCESS; } /* * main * */ int main() { XGpio GpioLeds, GpioButtons; XTmrCtr Timer; XScuGic Gic; TimerHandlerArg_t TimerHandlerArg; int Status; init_platform(); printf("Interrupt Example \n\r"); // Set up peripherals Status = SetupPeripherals(&GpioButtons, &GpioLeds, &Timer); if (Status != XST_SUCCESS) { printf("ERROR: Set up of peripherals failed \n\r"); return XST_FAILURE; } // Set up interrupts TimerHandlerArg.TimerPtr = &Timer; TimerHandlerArg.GpioLedsPtr = &GpioLeds; Status = SetupInterrupts(&Gic, &Timer, TimerHandler, &GpioButtons, GpioButtonsHandler, &TimerHandlerArg); if (Status != XST_SUCCESS) { printf("ERROR: Set up of interrupts subsystem failed \n\r"); return XST_FAILURE; } // Configure timer XTmrCtr_SetResetValue(&Timer, TIMER_COUNTER_0, 500000); XTmrCtr_SetOptions(&Timer, TIMER_COUNTER_0, XTC_INT_MODE_OPTION | XTC_DOWN_COUNT_OPTION | XTC_AUTO_RELOAD_OPTION); // Configure GPIO interrupts XGpio_InterruptEnable(&GpioButtons, XGPIO_IR_CH1_MASK); XGpio_InterruptGlobalEnable(&GpioButtons); // Globla interrupt enable Xil_ExceptionEnable(); // Start timer XTmrCtr_Start(&Timer, TIMER_COUNTER_0); // Main loop while(1) { #ifdef OPTION_A if (IntFlag) { if (Ascending) { XGpio_DiscreteWrite(&GpioLeds, 1, Step++); if (Step>63) Step=0; } else { XGpio_DiscreteWrite(&GpioLeds, 1, Step--); if (Step<0) Step=63; } IntFlag = 0; } #endif } // Exit (never reached) cleanup_platform(); return 0; }