Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:43

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  *  Timer Library (TLIB)
0005  *
0006  *  The Library rely on timer drivers, the timer presented by the
0007  *  timer driver must look like a down-counter timer, which generates
0008  *  interrupt (if configured) when underflown.
0009  *
0010  *  If Timer hardware is an up-counter the Timer driver must recalculate
0011  *  into values that would match as if it was a down-counter.
0012  *
0013  *  COPYRIGHT (c) 2011.
0014  *  Cobham Gaisler AB.
0015  *
0016  * Redistribution and use in source and binary forms, with or without
0017  * modification, are permitted provided that the following conditions
0018  * are met:
0019  * 1. Redistributions of source code must retain the above copyright
0020  *    notice, this list of conditions and the following disclaimer.
0021  * 2. Redistributions in binary form must reproduce the above copyright
0022  *    notice, this list of conditions and the following disclaimer in the
0023  *    documentation and/or other materials provided with the distribution.
0024  *
0025  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0026  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0028  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0029  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0030  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0031  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0032  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0033  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0034  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0035  * POSSIBILITY OF SUCH DAMAGE.
0036  */
0037 
0038 #ifndef __TLIB_H__
0039 #define __TLIB_H__
0040 
0041 #ifdef __cplusplus
0042 extern "C" {
0043 #endif
0044 
0045 struct tlib_dev;
0046 
0047 typedef void (*tlib_isr_t)(void *data);
0048 
0049 enum {
0050     TLIB_FLAGS_BROADCAST = 0x01
0051 };
0052 
0053 struct tlib_drv {
0054     /*** Functions ***/
0055     void    (*reset)(struct tlib_dev *hand);
0056     void    (*get_freq)(
0057         struct tlib_dev *hand,
0058         unsigned int *basefreq,
0059         unsigned int *tickrate);
0060     int (*set_freq)(struct tlib_dev *hand, unsigned int tickrate);
0061     void    (*irq_reg)(struct tlib_dev *hand, tlib_isr_t func, void *data, int flags);
0062     void    (*irq_unreg)(struct tlib_dev *hand, tlib_isr_t func,void *data);
0063     void    (*start)(struct tlib_dev *hand, int once);
0064     void    (*stop)(struct tlib_dev *hand);
0065     void    (*restart)(struct tlib_dev *hand);
0066     void    (*get_counter)(struct tlib_dev *hand, unsigned int *counter);
0067     int (*custom)(struct tlib_dev *hand, int cmd, void *arg);
0068     int (*int_pend)(struct tlib_dev *hand, int ack);
0069     void    (*get_widthmask)(struct tlib_dev *hand, unsigned int *widthmask);
0070 };
0071 
0072 struct tlib_dev {
0073     struct tlib_dev *next;
0074     char status; /* 0=closed, 1=open, 2=timer started */
0075     char index; /* Timer Index */
0076     tlib_isr_t isr_func;
0077     void *isr_data;
0078     struct tlib_drv *drv;
0079 };
0080 
0081 #ifdef RTEMS_DRVMGR_STARTUP
0082 /* Clock Driver Timer register function. Only used when the TLIB-Clock
0083  * driver is used. A specific Timer is registered as the System Clock
0084  * timer.
0085  */
0086 extern void Clock_timer_register(int timer_number);
0087 #endif
0088 
0089 /* Register Timer. Called by Timer Drivers in order to register
0090  * a Timer to the Timer Library. The registration order determines
0091  * the Timer Number used in tlib_open() to identify a specific
0092  * Timer.
0093  */
0094 extern int tlib_dev_reg(struct tlib_dev *newdev);
0095 
0096 /* Allocate a Timer.
0097  *
0098  * A Timer handle is returned identifying the timer in later calls.
0099  */
0100 extern void *tlib_open(int timer_no);
0101 
0102 /* Close Timer */
0103 extern void tlib_close(void *hand);
0104 
0105 /* Returns Number of Timers currently registered to Timer Library */
0106 extern int tlib_ntimer(void);
0107 
0108 static inline void tlib_reset(void *hand)
0109 {
0110     struct tlib_dev *dev = hand;
0111 
0112     dev->drv->reset(dev);
0113 }
0114 /* Get Frequencies:
0115  *   - Base Frequency (unchangable base freq rate of timer, prescaler, clkinput)
0116  *   - Current Tick Rate [in multiples of Base Frequency]
0117  */
0118 static inline void tlib_get_freq(
0119     void *hand,
0120     unsigned int *basefreq,
0121     unsigned int *tickrate)
0122 {
0123     struct tlib_dev *dev = hand;
0124 
0125     dev->drv->get_freq(dev, basefreq, tickrate);
0126 }
0127 
0128 /* Set current Tick Rate in number of "Base-Frequency ticks" */
0129 static inline int tlib_set_freq(void *hand, unsigned int tickrate)
0130 {
0131     struct tlib_dev *dev = hand;
0132 
0133     return dev->drv->set_freq(dev, tickrate);
0134 }
0135 
0136 /* Register ISR at Timer ISR */
0137 static inline void tlib_irq_unregister(void *hand)
0138 {
0139     struct tlib_dev *dev = hand;
0140 
0141     if ( dev->isr_func ) {
0142         dev->drv->irq_unreg(dev, dev->isr_func, dev->isr_data);
0143         dev->isr_func = NULL;
0144     }
0145 }
0146 
0147 /* Register ISR at Timer ISR */
0148 static inline void tlib_irq_register(void *hand, tlib_isr_t func, void *data, int flags)
0149 {
0150     struct tlib_dev *dev = hand;
0151 
0152     /* Unregister previous ISR if installed */
0153     tlib_irq_unregister(hand);
0154     dev->isr_func = func;
0155     dev->isr_data = data;
0156     dev->drv->irq_reg(dev, func, data, flags);
0157 }
0158 
0159 /* Start Timer, ISRs will be generated if enabled.
0160  *
0161  * once determines if timer should restart (=0) on underflow automatically,
0162  * or stop when underflow is reached (=1).
0163  */
0164 static inline void tlib_start(void *hand, int once)
0165 {
0166     struct tlib_dev *dev = hand;
0167 
0168     dev->drv->start(dev, once);
0169 }
0170 
0171 /* Stop Timer, no more ISRs will be generated */
0172 static inline void tlib_stop(void *hand)
0173 {
0174     struct tlib_dev *dev = hand;
0175 
0176     dev->drv->stop(dev);
0177 }
0178 
0179 /* Restart/Reload Timer, may be usefull if a Watchdog Timer */
0180 static inline void tlib_restart(void *hand)
0181 {
0182     struct tlib_dev *dev = hand;
0183 
0184     dev->drv->restart(dev);
0185 }
0186 
0187 /* Get current counter value (since last tick) */
0188 static inline void tlib_get_counter(void *hand, unsigned int *counter)
0189 {
0190     struct tlib_dev *dev = hand;
0191 
0192     dev->drv->get_counter(dev, counter);
0193 }
0194 
0195 /* Do a custom operation  */
0196 static inline void tlib_custom(void *hand, int cmd, void *arg)
0197 {
0198     struct tlib_dev *dev = hand;
0199 
0200     dev->drv->custom(dev, cmd, arg);
0201 }
0202 
0203 static inline int tlib_interrupt_pending(void *hand, int ack)
0204 {
0205     struct tlib_dev *dev = hand;
0206 
0207     return dev->drv->int_pend(dev, ack);
0208 }
0209 
0210 static inline void tlib_get_widthmask(void *hand, unsigned int *widthmask)
0211 {
0212     struct tlib_dev *dev = hand;
0213 
0214     dev->drv->get_widthmask(dev, widthmask);
0215 }
0216 
0217 #ifdef __cplusplus
0218 }
0219 #endif
0220 
0221 #endif