/** * * Runs a self-test on the timer driver/device. This test verifies that the * specified programmable interval timer of the device can be enabled and * increments. * * @param InstancePtr is a pointer to the XIOMOdule instance. * @param TimerNumber is the timer of the device to operate on. * Each device may contain multiple timers. The timer * number is a zero based number with a range of * 0 to (XTC_DEVICE_TIMER_COUNT - 1). * * @return * - XST_SUCCESS if self-test was successful * - XST_FAILURE if the timer is not incrementing. * * @note * * This is a destructive test using the provided timer. The current settings * of the timer are returned to the initialized values and all settings at the * time this function is called are overwritten. * ******************************************************************************/ int XIOModule_Timer_SelfTest(XIOModule * InstancePtr, u8 TimerNumber) { u32 TimerCount1 = 0; u32 TimerCount2 = 0; u16 Count = 0; /* * Assert the arguments */ Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid(TimerNumber < XTC_DEVICE_TIMER_COUNT); Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); /* * Set the Load register most significant bit to 1. */ XIOModule_SetResetValue(InstancePtr, TimerNumber, 1 << (InstancePtr->CfgPtr->PitSize[TimerNumber] - 1)); /* * Reset the timer and the interrupt */ XIOModule_Timer_SetOptions(InstancePtr, TimerNumber, 0); /* * Set the control/status register to enable timer */ XIOModule_Timer_Start(InstancePtr, TimerNumber); /* * Read the timer */ TimerCount1 = XIOModule_GetValue(InstancePtr, TimerNumber); /* * Make sure timer is decrementing if the Count rolls under zero * and the timer still has not decremented an error is returned */ do { TimerCount2 = XIOModule_GetValue(InstancePtr, TimerNumber); Count++; } while ((TimerCount1 == TimerCount2) && (Count != 0)); /* * Set the control/status register to 0 to complete initialization * this disables the timer completely and allows it to be used again */ XIOModule_Timer_Stop(InstancePtr, TimerNumber); if (TimerCount1 == TimerCount2) { return XST_FAILURE; } else { return XST_SUCCESS; } }
/** * This function does a minimal test on the IO Module device and driver as a * design example. The purpose of this function is to illustrate how to use the * IO Module component. It initializes the Programmable Interval Timers and * then sets it up in compare mode with auto reload such that a periodic * interrupt is generated. * * This function uses interrupt driven mode of the IO Module. * * @param IOModuleInstancePtr is a pointer to the IO Module driver * Instance * @param DeviceId is the XPAR_<IOModule_instance>_DEVICE_ID value from * xparameters.h * * @return XST_SUCCESS if the Test is successful, otherwise XST_FAILURE * * @note This function contains an infinite loop such that if interrupts * are not working it may never return. * *****************************************************************************/ XStatus IOModuleIntrExample(XIOModule *IOModuleInstancePtr, u16 DeviceId) { int Status; u8 Timer; XIOModule_Config *CfgPtr = IOModuleInstancePtr->CfgPtr; /* * Initialize the IO Module so that it's ready to use, specify the device * ID that is generated in xparameters.h */ Status = XIOModule_Initialize(IOModuleInstancePtr, DeviceId); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Perform a self-test to ensure that the hardware was built correctly. */ Status = XIOModule_SelfTest(IOModuleInstancePtr); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Initialize and enable interrupts in the processor. */ IOModuleSetupIntrSystem(IOModuleInstancePtr); /* * Setup the handler for the IO Module handler that will be called from * the interrupt context when an interrupt occurs, specify a pointer to * the IO Module driver instance as the callback reference so the * handler is able to access the instance data. */ XIOModule_SetHandler(IOModuleInstancePtr, IOModuleHandler, IOModuleInstancePtr); for (Timer = 0; Timer < XTC_DEVICE_TIMER_COUNT; Timer++) { /* * Skip unused timers,timers with prescaler (since they may * have very long expiration times), timers without readable * counters, and timers with small size (since the counter * may not change when sampled). */ if (! (CfgPtr->PitUsed[Timer] && CfgPtr->PitPrescaler[Timer] == XTC_PRESCALER_NONE && CfgPtr->PitReadable[Timer] && CfgPtr->PitSize[Timer] > MIN_TIMER_BITS)) { TimerExpired[Timer] = MAX_INTR_COUNT; continue; } /* * Use auto reload mode such that the Programmable Interval Timers will * reload automatically and continue repeatedly, without this option * they would expire once only */ XIOModule_Timer_SetOptions(IOModuleInstancePtr, Timer, XTC_INT_MODE_OPTION | XTC_AUTO_RELOAD_OPTION); /* * Set a reset value for the Programmable Interval Timers such that * they will expire earlier than letting them roll over from 0, the * reset value is loaded into the Programmable Interval Timers when * they are started. */ XIOModule_SetResetValue(IOModuleInstancePtr, Timer, RESET_VALUE); /* * Enable the interrupt for the Programmable Interval Timers. */ XIOModule_Enable(IOModuleInstancePtr, Timer + XIN_IOMODULE_PIT_1_INTERRUPT_INTR); /* * Start the Programmable Interval Timers such that they are * decrementing by default, then wait for them to timeout a number of * times. */ XIOModule_Timer_Start(IOModuleInstancePtr, Timer); } while (1) { int TotalExpiredCount = 0; /* * Wait for the Programmable Interval Timers to expire as indicated by * the shared variable which the handler will increment, and stop each * timer when it has reached the expected number of times. */ for (Timer = 0; Timer < XTC_DEVICE_TIMER_COUNT; Timer++) { if (TimerExpired[Timer] >= MAX_INTR_COUNT) XIOModule_Timer_Stop(IOModuleInstancePtr, Timer); TotalExpiredCount += TimerExpired[Timer]; } /* * If all timers have expired the expected number of times, then stop * this example. */ if (TotalExpiredCount == MAX_INTR_COUNT * XTC_DEVICE_TIMER_COUNT) { break; } } IOModuleDisableIntr(IOModuleInstancePtr); return XST_SUCCESS; }