]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/MicroBlaze_Kintex7_EthernetLite/BSP/microblaze_0/libsrc/tmrctr_v3_0/src/xtmrctr.c
Update some more standard demos for use on 64-bit architectures.
[freertos] / FreeRTOS / Demo / MicroBlaze_Kintex7_EthernetLite / BSP / microblaze_0 / libsrc / tmrctr_v3_0 / src / xtmrctr.c
1 /******************************************************************************
2 *
3 * Copyright (C) 2002 - 2014 Xilinx, Inc.  All rights reserved.
4 *
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:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
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.
18 *
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
25 * SOFTWARE.
26 *
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.
30 *
31 ******************************************************************************/
32 /*****************************************************************************/
33 /**
34 *
35 * @file xtmrctr.c
36 *
37 * Contains required functions for the XTmrCtr driver.
38 *
39 * <pre>
40 * MODIFICATION HISTORY:
41 *
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
48 *                     definitions.
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.
61 * </pre>
62 *
63 ******************************************************************************/
64
65 /***************************** Include Files *********************************/
66
67 #include "xstatus.h"
68 #include "xparameters.h"
69 #include "xtmrctr.h"
70 #include "xtmrctr_i.h"
71
72 /************************** Constant Definitions *****************************/
73
74
75 /**************************** Type Definitions *******************************/
76
77
78 /***************** Macros (Inline Functions) Definitions *********************/
79
80
81 /************************** Function Prototypes ******************************/
82
83
84 /************************** Variable Definitions *****************************/
85
86
87 /*****************************************************************************/
88 /**
89 *
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.
93 *
94 *
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.
100 *
101 * @return
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
105 *
106 * @note         None.
107 *
108 ******************************************************************************/
109 int XTmrCtr_Initialize(XTmrCtr * InstancePtr, u16 DeviceId)
110 {
111         XTmrCtr_Config *TmrCtrConfigPtr;
112         int TmrCtrNumber;
113         int TmrCtrLowIndex = 0;
114         int TmrCtrHighIndex = XTC_DEVICE_TIMER_COUNT;
115
116         Xil_AssertNonvoid(InstancePtr != NULL);
117
118
119         /*
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
123          * initializing.
124          * In case one of the timers has not started then that particular timer
125          * will be initialized
126          */
127         if ((InstancePtr->IsStartedTmrCtr0 == XIL_COMPONENT_IS_STARTED) &&
128             (InstancePtr->IsStartedTmrCtr1 == XIL_COMPONENT_IS_STARTED)) {
129                 return XST_DEVICE_IS_STARTED;
130         }
131
132
133         /*
134          * Ensure that only the timer which is NOT started can be initialized
135          */
136         if ((InstancePtr->IsStartedTmrCtr0 == XIL_COMPONENT_IS_STARTED)) {
137                 TmrCtrLowIndex = 1;
138         } else if ((InstancePtr->IsStartedTmrCtr1 == XIL_COMPONENT_IS_STARTED)) {
139                 TmrCtrHighIndex = 1;
140         } else {
141                 InstancePtr->IsStartedTmrCtr0 = 0;
142                 InstancePtr->IsStartedTmrCtr1 = 0;
143         }
144
145
146
147         /*
148          * Lookup the device configuration in the temporary CROM table. Use this
149          * configuration info down below when initializing this component.
150          */
151         TmrCtrConfigPtr = XTmrCtr_LookupConfig(DeviceId);
152
153         if (TmrCtrConfigPtr == (XTmrCtr_Config *) NULL) {
154                 return XST_DEVICE_NOT_FOUND;
155         }
156
157         /*
158          * Set some default values, including setting the callback
159          * handlers to stubs.
160          */
161         InstancePtr->BaseAddress = TmrCtrConfigPtr->BaseAddress;
162         InstancePtr->Handler = NULL;
163         InstancePtr->CallBackRef = NULL;
164
165         /*
166          * Clear the statistics for this driver
167          */
168         InstancePtr->Stats.Interrupts = 0;
169
170         /* Initialize the registers of each timer/counter in the device */
171
172         for (TmrCtrNumber = TmrCtrLowIndex; TmrCtrNumber < TmrCtrHighIndex;
173              TmrCtrNumber++) {
174
175                 /*
176                  * Set the Compare register to 0
177                  */
178                 XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
179                                   XTC_TLR_OFFSET, 0);
180                 /*
181                  * Reset the timer and the interrupt, the reset bit will need to
182                  * be cleared after this
183                  */
184                 XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
185                                   XTC_TCSR_OFFSET,
186                                   XTC_CSR_INT_OCCURED_MASK | XTC_CSR_LOAD_MASK);
187                 /*
188                  * Set the control/status register to complete initialization by
189                  * clearing the reset bit which was just set
190                  */
191                 XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
192                                   XTC_TCSR_OFFSET, 0);
193         }
194
195         /*
196          * Indicate the instance is ready to use, successfully initialized
197          */
198         InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
199
200         return XST_SUCCESS;
201 }
202
203 /*****************************************************************************/
204 /**
205 *
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.
209 *
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.
214 *
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).
220 *
221 * @return       None.
222 *
223 * @note         None.
224 *
225 ******************************************************************************/
226 void XTmrCtr_Start(XTmrCtr * InstancePtr, u8 TmrCtrNumber)
227 {
228         u32 ControlStatusReg;
229
230         Xil_AssertVoid(InstancePtr != NULL);
231         Xil_AssertVoid(TmrCtrNumber < XTC_DEVICE_TIMER_COUNT);
232         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
233
234         /*
235          * Read the current register contents such that only the necessary bits
236          * of the register are modified in the following operations
237          */
238         ControlStatusReg = XTmrCtr_ReadReg(InstancePtr->BaseAddress,
239                                               TmrCtrNumber, XTC_TCSR_OFFSET);
240         /*
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
244          * cleared
245          */
246         XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
247                           XTC_TCSR_OFFSET,
248                           XTC_CSR_LOAD_MASK);
249
250
251
252         /*
253          * Indicate that the timer is started before enabling it
254          */
255         if (TmrCtrNumber == 0) {
256                 InstancePtr->IsStartedTmrCtr0 = XIL_COMPONENT_IS_STARTED;
257         } else {
258                 InstancePtr->IsStartedTmrCtr1 = XIL_COMPONENT_IS_STARTED;
259         }
260
261
262         /*
263          * Remove the reset condition such that the timer counter starts running
264          * with the value loaded from the compare register
265          */
266         XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
267                           XTC_TCSR_OFFSET,
268                           ControlStatusReg | XTC_CSR_ENABLE_TMR_MASK);
269 }
270
271 /*****************************************************************************/
272 /**
273 *
274 * Stops the timer counter by disabling it.
275 *
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.
279 *
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).
285 *
286 * @return       None.
287 *
288 * @note         None.
289 *
290 ******************************************************************************/
291 void XTmrCtr_Stop(XTmrCtr * InstancePtr, u8 TmrCtrNumber)
292 {
293         u32 ControlStatusReg;
294
295         Xil_AssertVoid(InstancePtr != NULL);
296         Xil_AssertVoid(TmrCtrNumber < XTC_DEVICE_TIMER_COUNT);
297         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
298
299         /*
300          * Read the current register contents
301          */
302         ControlStatusReg = XTmrCtr_ReadReg(InstancePtr->BaseAddress,
303                                               TmrCtrNumber, XTC_TCSR_OFFSET);
304         /*
305          * Disable the timer counter such that it's not running
306          */
307         ControlStatusReg &= ~(XTC_CSR_ENABLE_TMR_MASK);
308
309         /*
310          * Write out the updated value to the actual register.
311          */
312         XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
313                           XTC_TCSR_OFFSET, ControlStatusReg);
314
315         /*
316          * Indicate that the timer is stopped
317          */
318         if (TmrCtrNumber == 0) {
319                 InstancePtr->IsStartedTmrCtr0 = 0;
320         } else {
321                 InstancePtr->IsStartedTmrCtr1 = 0;
322         }
323 }
324
325 /*****************************************************************************/
326 /**
327 *
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
330 * operation.
331 *
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).
337 *
338 * @return       The current value for the timer counter.
339 *
340 * @note         None.
341 *
342 ******************************************************************************/
343 u32 XTmrCtr_GetValue(XTmrCtr * InstancePtr, u8 TmrCtrNumber)
344 {
345
346         Xil_AssertNonvoid(InstancePtr != NULL);
347         Xil_AssertNonvoid(TmrCtrNumber < XTC_DEVICE_TIMER_COUNT);
348         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
349
350         return XTmrCtr_ReadReg(InstancePtr->BaseAddress,
351                                   TmrCtrNumber, XTC_TCR_OFFSET);
352 }
353
354 /*****************************************************************************/
355 /**
356 *
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.
360 *
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
367 *               counter.
368 *
369 * @return       None.
370 *
371 * @note         None.
372 *
373 ******************************************************************************/
374 void XTmrCtr_SetResetValue(XTmrCtr * InstancePtr, u8 TmrCtrNumber,
375                            u32 ResetValue)
376 {
377
378         Xil_AssertVoid(InstancePtr != NULL);
379         Xil_AssertVoid(TmrCtrNumber < XTC_DEVICE_TIMER_COUNT);
380         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
381
382         XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
383                           XTC_TLR_OFFSET, ResetValue);
384 }
385
386 /*****************************************************************************/
387 /**
388 *
389 * Returns the timer counter value that was captured the last time the external
390 * capture input was asserted.
391 *
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).
397 *
398 * @return       The current capture value for the indicated timer counter.
399 *
400 * @note         None.
401 *
402 *******************************************************************************/
403 u32 XTmrCtr_GetCaptureValue(XTmrCtr * InstancePtr, u8 TmrCtrNumber)
404 {
405
406         Xil_AssertNonvoid(InstancePtr != NULL);
407         Xil_AssertNonvoid(TmrCtrNumber < XTC_DEVICE_TIMER_COUNT);
408         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
409
410         return XTmrCtr_ReadReg(InstancePtr->BaseAddress,
411                                   TmrCtrNumber, XTC_TLR_OFFSET);
412 }
413
414 /*****************************************************************************/
415 /**
416 *
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.
419 *
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).
425 *
426 * @return       None.
427 *
428 * @note         None.
429 *
430 ******************************************************************************/
431 void XTmrCtr_Reset(XTmrCtr * InstancePtr, u8 TmrCtrNumber)
432 {
433         u32 CounterControlReg;
434
435         Xil_AssertVoid(InstancePtr != NULL);
436         Xil_AssertVoid(TmrCtrNumber < XTC_DEVICE_TIMER_COUNT);
437         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
438
439         /*
440          * Read current contents of the register so it won't be destroyed
441          */
442         CounterControlReg = XTmrCtr_ReadReg(InstancePtr->BaseAddress,
443                                                TmrCtrNumber, XTC_TCSR_OFFSET);
444         /*
445          * Reset the timer by toggling the reset bit in the register
446          */
447         XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
448                           XTC_TCSR_OFFSET,
449                           CounterControlReg | XTC_CSR_LOAD_MASK);
450
451         XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
452                           XTC_TCSR_OFFSET, CounterControlReg);
453 }
454
455 /*****************************************************************************/
456 /**
457 *
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.
461 *
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.
464 *
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).
470 *
471 * @return       TRUE if the timer has expired, and FALSE otherwise.
472 *
473 * @note         None.
474 *
475 ******************************************************************************/
476 int XTmrCtr_IsExpired(XTmrCtr * InstancePtr, u8 TmrCtrNumber)
477 {
478         u32 CounterControlReg;
479
480         Xil_AssertNonvoid(InstancePtr != NULL);
481         Xil_AssertNonvoid(TmrCtrNumber < XTC_DEVICE_TIMER_COUNT);
482         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
483
484         /*
485          * Check if timer is expired
486          */
487         CounterControlReg = XTmrCtr_ReadReg(InstancePtr->BaseAddress,
488                                                TmrCtrNumber, XTC_TCSR_OFFSET);
489
490         return ((CounterControlReg & XTC_CSR_INT_OCCURED_MASK) ==
491                 XTC_CSR_INT_OCCURED_MASK);
492 }
493
494 /*****************************************************************************
495 *
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
498 * system.
499 *
500 * @param        DeviceId is the unique device ID to search for in the config
501 *               table.
502 *
503 * @return       A pointer to the configuration that matches the given device ID,
504 *               or NULL if no match is found.
505 *
506 * @note         None.
507 *
508 ******************************************************************************/
509 XTmrCtr_Config *XTmrCtr_LookupConfig(u16 DeviceId)
510 {
511         XTmrCtr_Config *CfgPtr = NULL;
512         int Index;
513
514         for (Index = 0; Index < XPAR_XTMRCTR_NUM_INSTANCES; Index++) {
515                 if (XTmrCtr_ConfigTable[Index].DeviceId == DeviceId) {
516                         CfgPtr = &XTmrCtr_ConfigTable[Index];
517                         break;
518                 }
519         }
520
521         return CfgPtr;
522 }