RTEMS  5.1
tlib.h
1 /*
2  * Timer Library (TLIB)
3  *
4  * The Library rely on timer drivers, the timer presented by the
5  * timer driver must look like a down-counter timer, which generates
6  * interrupt (if configured) when underflown.
7  *
8  * If Timer hardware is an up-counter the Timer driver must recalculate
9  * into values that would match as if it was a down-counter.
10  *
11  * COPYRIGHT (c) 2011.
12  * Cobham Gaisler AB.
13  *
14  * The license and distribution terms for this file may be
15  * found in the file LICENSE in this distribution or at
16  * http://www.rtems.org/license/LICENSE.
17  */
18 
19 #ifndef __TLIB_H__
20 #define __TLIB_H__
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25 
26 struct tlib_dev;
27 
28 typedef void (*tlib_isr_t)(void *data);
29 
30 enum {
31  TLIB_FLAGS_BROADCAST = 0x01
32 };
33 
34 struct tlib_drv {
35  /*** Functions ***/
36  void (*reset)(struct tlib_dev *hand);
37  void (*get_freq)(
38  struct tlib_dev *hand,
39  unsigned int *basefreq,
40  unsigned int *tickrate);
41  int (*set_freq)(struct tlib_dev *hand, unsigned int tickrate);
42  void (*irq_reg)(struct tlib_dev *hand, tlib_isr_t func, void *data, int flags);
43  void (*irq_unreg)(struct tlib_dev *hand, tlib_isr_t func,void *data);
44  void (*start)(struct tlib_dev *hand, int once);
45  void (*stop)(struct tlib_dev *hand);
46  void (*restart)(struct tlib_dev *hand);
47  void (*get_counter)(struct tlib_dev *hand, unsigned int *counter);
48  int (*custom)(struct tlib_dev *hand, int cmd, void *arg);
49  int (*int_pend)(struct tlib_dev *hand, int ack);
50  void (*get_widthmask)(struct tlib_dev *hand, unsigned int *widthmask);
51 };
52 
53 struct tlib_dev {
54  struct tlib_dev *next;
55  char status; /* 0=closed, 1=open, 2=timer started */
56  char index; /* Timer Index */
57  tlib_isr_t isr_func;
58  void *isr_data;
59  struct tlib_drv *drv;
60 };
61 
62 #ifdef RTEMS_DRVMGR_STARTUP
63 /* Clock Driver Timer register function. Only used when the TLIB-Clock
64  * driver is used. A specific Timer is registered as the System Clock
65  * timer.
66  */
67 extern void Clock_timer_register(int timer_number);
68 #endif
69 
70 /* Register Timer. Called by Timer Drivers in order to register
71  * a Timer to the Timer Library. The registration order determines
72  * the Timer Number used in tlib_open() to identify a specific
73  * Timer.
74  */
75 extern int tlib_dev_reg(struct tlib_dev *newdev);
76 
77 /* Allocate a Timer.
78  *
79  * A Timer handle is returned identifying the timer in later calls.
80  */
81 extern void *tlib_open(int timer_no);
82 
83 /* Close Timer */
84 extern void tlib_close(void *hand);
85 
86 /* Returns Number of Timers currently registered to Timer Library */
87 extern int tlib_ntimer(void);
88 
89 static inline void tlib_reset(void *hand)
90 {
91  struct tlib_dev *dev = hand;
92 
93  dev->drv->reset(dev);
94 }
95 /* Get Frequencies:
96  * - Base Frequency (unchangable base freq rate of timer, prescaler, clkinput)
97  * - Current Tick Rate [in multiples of Base Frequency]
98  */
99 static inline void tlib_get_freq(
100  void *hand,
101  unsigned int *basefreq,
102  unsigned int *tickrate)
103 {
104  struct tlib_dev *dev = hand;
105 
106  dev->drv->get_freq(dev, basefreq, tickrate);
107 }
108 
109 /* Set current Tick Rate in number of "Base-Frequency ticks" */
110 static inline int tlib_set_freq(void *hand, unsigned int tickrate)
111 {
112  struct tlib_dev *dev = hand;
113 
114  return dev->drv->set_freq(dev, tickrate);
115 }
116 
117 /* Register ISR at Timer ISR */
118 static inline void tlib_irq_unregister(void *hand)
119 {
120  struct tlib_dev *dev = hand;
121 
122  if ( dev->isr_func ) {
123  dev->drv->irq_unreg(dev, dev->isr_func, dev->isr_data);
124  dev->isr_func = NULL;
125  }
126 }
127 
128 /* Register ISR at Timer ISR */
129 static inline void tlib_irq_register(void *hand, tlib_isr_t func, void *data, int flags)
130 {
131  struct tlib_dev *dev = hand;
132 
133  /* Unregister previous ISR if installed */
134  tlib_irq_unregister(hand);
135  dev->isr_func = func;
136  dev->isr_data = data;
137  dev->drv->irq_reg(dev, func, data, flags);
138 }
139 
140 /* Start Timer, ISRs will be generated if enabled.
141  *
142  * once determines if timer should restart (=0) on underflow automatically,
143  * or stop when underflow is reached (=1).
144  */
145 static inline void tlib_start(void *hand, int once)
146 {
147  struct tlib_dev *dev = hand;
148 
149  dev->drv->start(dev, once);
150 }
151 
152 /* Stop Timer, no more ISRs will be generated */
153 static inline void tlib_stop(void *hand)
154 {
155  struct tlib_dev *dev = hand;
156 
157  dev->drv->stop(dev);
158 }
159 
160 /* Restart/Reload Timer, may be usefull if a Watchdog Timer */
161 static inline void tlib_restart(void *hand)
162 {
163  struct tlib_dev *dev = hand;
164 
165  dev->drv->restart(dev);
166 }
167 
168 /* Get current counter value (since last tick) */
169 static inline void tlib_get_counter(void *hand, unsigned int *counter)
170 {
171  struct tlib_dev *dev = hand;
172 
173  dev->drv->get_counter(dev, counter);
174 }
175 
176 /* Do a custom operation */
177 static inline void tlib_custom(void *hand, int cmd, void *arg)
178 {
179  struct tlib_dev *dev = hand;
180 
181  dev->drv->custom(dev, cmd, arg);
182 }
183 
184 static inline int tlib_interrupt_pending(void *hand, int ack)
185 {
186  struct tlib_dev *dev = hand;
187 
188  return dev->drv->int_pend(dev, ack);
189 }
190 
191 static inline void tlib_get_widthmask(void *hand, unsigned int *widthmask)
192 {
193  struct tlib_dev *dev = hand;
194 
195  dev->drv->get_widthmask(dev, widthmask);
196 }
197 
198 #ifdef __cplusplus
199 }
200 #endif
201 
202 #endif
Definition: tlib.h:53
Definition: tlib.h:34
#define NULL
Requests a GPIO pin group configuration.
Definition: bestcomm_api.h:77