1 /******************************************************************************
3 * Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * Use of the Software is limited solely to applications:
16 * (a) running on a Xilinx device, or
17 * (b) that interact with a Xilinx device through a bus or interconnect.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
24 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 * Except as contained in this notice, the name of the Xilinx shall not be used
28 * in advertising or otherwise to promote the sale, use or other dealings in
29 * this Software without prior written authorization from Xilinx.
31 ******************************************************************************/
32 /*****************************************************************************/
37 * Contains required functions for the XTmrCtr driver.
40 * MODIFICATION HISTORY:
42 * Ver Who Date Changes
43 * ----- ---- -------- -----------------------------------------------
44 * 1.00a ecm 08/16/01 First release
45 * 1.00b jhl 02/21/02 Repartitioned the driver for smaller files
46 * 1.10b mta 03/21/07 Updated to new coding style
47 * 2.00a ktn 10/30/09 Updated to use HAL API's. _m is removed from all the macro
49 * 2.05a adk 15/05/13 Fixed the CR:693066
50 * Added the IsStartedTmrCtr0/IsStartedTmrCtr1 members to the
51 * XTmrCtr instance structure.
52 * The IsStartedTmrCtrX will be assigned XIL_COMPONENT_IS_STARTED in
53 * the XTmrCtr_Start function.
54 * The IsStartedTmrCtrX will be cleared in the XTmrCtr_Stop function.
55 * There will be no Initialization done in the
56 * XTmrCtr_Initialize if both the timers have already started and
57 * the XST_DEVICE_IS_STARTED Status is returned.
58 * Removed the logic in the XTmrCtr_Initialize function
59 * which was checking the Register Value to know whether
60 * a timer has started or not.
63 ******************************************************************************/
65 /***************************** Include Files *********************************/
68 #include "xparameters.h"
70 #include "xtmrctr_i.h"
72 /************************** Constant Definitions *****************************/
75 /**************************** Type Definitions *******************************/
78 /***************** Macros (Inline Functions) Definitions *********************/
81 /************************** Function Prototypes ******************************/
84 /************************** Variable Definitions *****************************/
87 /*****************************************************************************/
90 * Initializes a specific timer/counter instance/driver. Initialize fields of
91 * the XTmrCtr structure, then reset the timer/counter.If a timer is already
92 * running then it is not initialized.
95 * @param InstancePtr is a pointer to the XTmrCtr instance.
96 * @param DeviceId is the unique id of the device controlled by this
97 * XTmrCtr component. Passing in a device id associates the
98 * generic XTmrCtr component to a specific device, as chosen by
99 * the caller or application developer.
102 * - XST_SUCCESS if initialization was successful
103 * - XST_DEVICE_IS_STARTED if the device has already been started
104 * - XST_DEVICE_NOT_FOUND if the device doesn't exist
108 ******************************************************************************/
109 int XTmrCtr_Initialize(XTmrCtr * InstancePtr, u16 DeviceId)
111 XTmrCtr_Config *TmrCtrConfigPtr;
113 int TmrCtrLowIndex = 0;
114 int TmrCtrHighIndex = XTC_DEVICE_TIMER_COUNT;
116 Xil_AssertNonvoid(InstancePtr != NULL);
120 * If both the timers have already started, disallow the initialize and
121 * return a status indicating it is started. This allows the user to stop
122 * the device and reinitialize, but prevents a user from inadvertently
124 * In case one of the timers has not started then that particular timer
125 * will be initialized
127 if ((InstancePtr->IsStartedTmrCtr0 == XIL_COMPONENT_IS_STARTED) &&
128 (InstancePtr->IsStartedTmrCtr1 == XIL_COMPONENT_IS_STARTED)) {
129 return XST_DEVICE_IS_STARTED;
134 * Ensure that only the timer which is NOT started can be initialized
136 if ((InstancePtr->IsStartedTmrCtr0 == XIL_COMPONENT_IS_STARTED)) {
138 } else if ((InstancePtr->IsStartedTmrCtr1 == XIL_COMPONENT_IS_STARTED)) {
141 InstancePtr->IsStartedTmrCtr0 = 0;
142 InstancePtr->IsStartedTmrCtr1 = 0;
148 * Lookup the device configuration in the temporary CROM table. Use this
149 * configuration info down below when initializing this component.
151 TmrCtrConfigPtr = XTmrCtr_LookupConfig(DeviceId);
153 if (TmrCtrConfigPtr == (XTmrCtr_Config *) NULL) {
154 return XST_DEVICE_NOT_FOUND;
158 * Set some default values, including setting the callback
161 InstancePtr->BaseAddress = TmrCtrConfigPtr->BaseAddress;
162 InstancePtr->Handler = NULL;
163 InstancePtr->CallBackRef = NULL;
166 * Clear the statistics for this driver
168 InstancePtr->Stats.Interrupts = 0;
170 /* Initialize the registers of each timer/counter in the device */
172 for (TmrCtrNumber = TmrCtrLowIndex; TmrCtrNumber < TmrCtrHighIndex;
176 * Set the Compare register to 0
178 XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
181 * Reset the timer and the interrupt, the reset bit will need to
182 * be cleared after this
184 XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
186 XTC_CSR_INT_OCCURED_MASK | XTC_CSR_LOAD_MASK);
188 * Set the control/status register to complete initialization by
189 * clearing the reset bit which was just set
191 XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
196 * Indicate the instance is ready to use, successfully initialized
198 InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
203 /*****************************************************************************/
206 * Starts the specified timer counter of the device such that it starts running.
207 * The timer counter is reset before it is started and the reset value is
208 * loaded into the timer counter.
210 * If interrupt mode is specified in the options, it is necessary for the caller
211 * to connect the interrupt handler of the timer/counter to the interrupt source,
212 * typically an interrupt controller, and enable the interrupt within the
213 * interrupt controller.
215 * @param InstancePtr is a pointer to the XTmrCtr instance.
216 * @param TmrCtrNumber is the timer counter of the device to operate on.
217 * Each device may contain multiple timer counters. The timer
218 * number is a zero based number with a range of
219 * 0 - (XTC_DEVICE_TIMER_COUNT - 1).
225 ******************************************************************************/
226 void XTmrCtr_Start(XTmrCtr * InstancePtr, u8 TmrCtrNumber)
228 u32 ControlStatusReg;
230 Xil_AssertVoid(InstancePtr != NULL);
231 Xil_AssertVoid(TmrCtrNumber < XTC_DEVICE_TIMER_COUNT);
232 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
235 * Read the current register contents such that only the necessary bits
236 * of the register are modified in the following operations
238 ControlStatusReg = XTmrCtr_ReadReg(InstancePtr->BaseAddress,
239 TmrCtrNumber, XTC_TCSR_OFFSET);
241 * Reset the timer counter such that it reloads from the compare
242 * register and the interrupt is cleared simultaneously, the interrupt
243 * can only be cleared after reset such that the interrupt condition is
246 XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
253 * Indicate that the timer is started before enabling it
255 if (TmrCtrNumber == 0) {
256 InstancePtr->IsStartedTmrCtr0 = XIL_COMPONENT_IS_STARTED;
258 InstancePtr->IsStartedTmrCtr1 = XIL_COMPONENT_IS_STARTED;
263 * Remove the reset condition such that the timer counter starts running
264 * with the value loaded from the compare register
266 XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
268 ControlStatusReg | XTC_CSR_ENABLE_TMR_MASK);
271 /*****************************************************************************/
274 * Stops the timer counter by disabling it.
276 * It is the callers' responsibility to disconnect the interrupt handler of the
277 * timer_counter from the interrupt source, typically an interrupt controller,
278 * and disable the interrupt within the interrupt controller.
280 * @param InstancePtr is a pointer to the XTmrCtr instance.
281 * @param TmrCtrNumber is the timer counter of the device to operate on.
282 * Each device may contain multiple timer counters. The timer
283 * number is a zero based number with a range of
284 * 0 - (XTC_DEVICE_TIMER_COUNT - 1).
290 ******************************************************************************/
291 void XTmrCtr_Stop(XTmrCtr * InstancePtr, u8 TmrCtrNumber)
293 u32 ControlStatusReg;
295 Xil_AssertVoid(InstancePtr != NULL);
296 Xil_AssertVoid(TmrCtrNumber < XTC_DEVICE_TIMER_COUNT);
297 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
300 * Read the current register contents
302 ControlStatusReg = XTmrCtr_ReadReg(InstancePtr->BaseAddress,
303 TmrCtrNumber, XTC_TCSR_OFFSET);
305 * Disable the timer counter such that it's not running
307 ControlStatusReg &= ~(XTC_CSR_ENABLE_TMR_MASK);
310 * Write out the updated value to the actual register.
312 XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
313 XTC_TCSR_OFFSET, ControlStatusReg);
316 * Indicate that the timer is stopped
318 if (TmrCtrNumber == 0) {
319 InstancePtr->IsStartedTmrCtr0 = 0;
321 InstancePtr->IsStartedTmrCtr1 = 0;
325 /*****************************************************************************/
328 * Get the current value of the specified timer counter. The timer counter
329 * may be either incrementing or decrementing based upon the current mode of
332 * @param InstancePtr is a pointer to the XTmrCtr instance.
333 * @param TmrCtrNumber is the timer counter of the device to operate on.
334 * Each device may contain multiple timer counters. The timer
335 * number is a zero based number with a range of
336 * 0 - (XTC_DEVICE_TIMER_COUNT - 1).
338 * @return The current value for the timer counter.
342 ******************************************************************************/
343 u32 XTmrCtr_GetValue(XTmrCtr * InstancePtr, u8 TmrCtrNumber)
346 Xil_AssertNonvoid(InstancePtr != NULL);
347 Xil_AssertNonvoid(TmrCtrNumber < XTC_DEVICE_TIMER_COUNT);
348 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
350 return XTmrCtr_ReadReg(InstancePtr->BaseAddress,
351 TmrCtrNumber, XTC_TCR_OFFSET);
354 /*****************************************************************************/
357 * Set the reset value for the specified timer counter. This is the value
358 * that is loaded into the timer counter when it is reset. This value is also
359 * loaded when the timer counter is started.
361 * @param InstancePtr is a pointer to the XTmrCtr instance.
362 * @param TmrCtrNumber is the timer counter of the device to operate on.
363 * Each device may contain multiple timer counters. The timer
364 * number is a zero based number with a range of
365 * 0 - (XTC_DEVICE_TIMER_COUNT - 1).
366 * @param ResetValue contains the value to be used to reset the timer
373 ******************************************************************************/
374 void XTmrCtr_SetResetValue(XTmrCtr * InstancePtr, u8 TmrCtrNumber,
378 Xil_AssertVoid(InstancePtr != NULL);
379 Xil_AssertVoid(TmrCtrNumber < XTC_DEVICE_TIMER_COUNT);
380 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
382 XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
383 XTC_TLR_OFFSET, ResetValue);
386 /*****************************************************************************/
389 * Returns the timer counter value that was captured the last time the external
390 * capture input was asserted.
392 * @param InstancePtr is a pointer to the XTmrCtr instance.
393 * @param TmrCtrNumber is the timer counter of the device to operate on.
394 * Each device may contain multiple timer counters. The timer
395 * number is a zero based number with a range of
396 * 0 - (XTC_DEVICE_TIMER_COUNT - 1).
398 * @return The current capture value for the indicated timer counter.
402 *******************************************************************************/
403 u32 XTmrCtr_GetCaptureValue(XTmrCtr * InstancePtr, u8 TmrCtrNumber)
406 Xil_AssertNonvoid(InstancePtr != NULL);
407 Xil_AssertNonvoid(TmrCtrNumber < XTC_DEVICE_TIMER_COUNT);
408 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
410 return XTmrCtr_ReadReg(InstancePtr->BaseAddress,
411 TmrCtrNumber, XTC_TLR_OFFSET);
414 /*****************************************************************************/
417 * Resets the specified timer counter of the device. A reset causes the timer
418 * counter to set it's value to the reset value.
420 * @param InstancePtr is a pointer to the XTmrCtr instance.
421 * @param TmrCtrNumber is the timer counter of the device to operate on.
422 * Each device may contain multiple timer counters. The timer
423 * number is a zero based number with a range of
424 * 0 - (XTC_DEVICE_TIMER_COUNT - 1).
430 ******************************************************************************/
431 void XTmrCtr_Reset(XTmrCtr * InstancePtr, u8 TmrCtrNumber)
433 u32 CounterControlReg;
435 Xil_AssertVoid(InstancePtr != NULL);
436 Xil_AssertVoid(TmrCtrNumber < XTC_DEVICE_TIMER_COUNT);
437 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
440 * Read current contents of the register so it won't be destroyed
442 CounterControlReg = XTmrCtr_ReadReg(InstancePtr->BaseAddress,
443 TmrCtrNumber, XTC_TCSR_OFFSET);
445 * Reset the timer by toggling the reset bit in the register
447 XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
449 CounterControlReg | XTC_CSR_LOAD_MASK);
451 XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
452 XTC_TCSR_OFFSET, CounterControlReg);
455 /*****************************************************************************/
458 * Checks if the specified timer counter of the device has expired. In capture
459 * mode, expired is defined as a capture occurred. In compare mode, expired is
460 * defined as the timer counter rolled over/under for up/down counting.
462 * When interrupts are enabled, the expiration causes an interrupt. This function
463 * is typically used to poll a timer counter to determine when it has expired.
465 * @param InstancePtr is a pointer to the XTmrCtr instance.
466 * @param TmrCtrNumber is the timer counter of the device to operate on.
467 * Each device may contain multiple timer counters. The timer
468 * number is a zero based number with a range of
469 * 0 - (XTC_DEVICE_TIMER_COUNT - 1).
471 * @return TRUE if the timer has expired, and FALSE otherwise.
475 ******************************************************************************/
476 int XTmrCtr_IsExpired(XTmrCtr * InstancePtr, u8 TmrCtrNumber)
478 u32 CounterControlReg;
480 Xil_AssertNonvoid(InstancePtr != NULL);
481 Xil_AssertNonvoid(TmrCtrNumber < XTC_DEVICE_TIMER_COUNT);
482 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
485 * Check if timer is expired
487 CounterControlReg = XTmrCtr_ReadReg(InstancePtr->BaseAddress,
488 TmrCtrNumber, XTC_TCSR_OFFSET);
490 return ((CounterControlReg & XTC_CSR_INT_OCCURED_MASK) ==
491 XTC_CSR_INT_OCCURED_MASK);
494 /*****************************************************************************
496 * Looks up the device configuration based on the unique device ID. The table
497 * TmrCtrConfigTable contains the configuration info for each device in the
500 * @param DeviceId is the unique device ID to search for in the config
503 * @return A pointer to the configuration that matches the given device ID,
504 * or NULL if no match is found.
508 ******************************************************************************/
509 XTmrCtr_Config *XTmrCtr_LookupConfig(u16 DeviceId)
511 XTmrCtr_Config *CfgPtr = NULL;
514 for (Index = 0; Index < XPAR_XTMRCTR_NUM_INSTANCES; Index++) {
515 if (XTmrCtr_ConfigTable[Index].DeviceId == DeviceId) {
516 CfgPtr = &XTmrCtr_ConfigTable[Index];