diff options
Diffstat (limited to 'include/bsp/tlib.h')
-rw-r--r-- | include/bsp/tlib.h | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/include/bsp/tlib.h b/include/bsp/tlib.h new file mode 100644 index 0000000000..7e6c49ae62 --- /dev/null +++ b/include/bsp/tlib.h @@ -0,0 +1,190 @@ +/* + * Timer Library (TLIB) + * + * The Library rely on timer drivers, the timer presented by the + * timer driver must look like a down-counter timer, which generates + * interrupt (if configured) when underflown. + * + * If Timer hardware is an up-counter the Timer driver must recalculate + * into values that would match as if it was a down-counter. + * + * COPYRIGHT (c) 2011. + * Cobham Gaisler AB. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef __TLIB_H__ +#define __TLIB_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +struct tlib_dev; + +typedef void (*tlib_isr_t)(void *data); + +struct tlib_drv { + /*** Functions ***/ + void (*reset)(struct tlib_dev *hand); + void (*get_freq)( + struct tlib_dev *hand, + unsigned int *basefreq, + unsigned int *tickrate); + int (*set_freq)(struct tlib_dev *hand, unsigned int tickrate); + void (*irq_reg)(struct tlib_dev *hand, tlib_isr_t func, void *data); + void (*irq_unreg)(struct tlib_dev *hand, tlib_isr_t func,void *data); + void (*start)(struct tlib_dev *hand, int once); + void (*stop)(struct tlib_dev *hand); + void (*restart)(struct tlib_dev *hand); + void (*get_counter)(struct tlib_dev *hand, unsigned int *counter); + int (*custom)(struct tlib_dev *hand, int cmd, void *arg); + int (*int_pend)(struct tlib_dev *hand, int ack); +}; + +struct tlib_dev { + struct tlib_dev *next; + char status; /* 0=closed, 1=open, 2=timer started */ + char index; /* Timer Index */ + tlib_isr_t isr_func; + void *isr_data; + struct tlib_drv *drv; +}; + +#ifdef RTEMS_DRVMGR_STARTUP +/* Clock Driver Timer register function. Only used when the TLIB-Clock + * driver is used. A specific Timer is registered as the System Clock + * timer. + */ +extern void Clock_timer_register(int timer_number); +#endif + +/* Register Timer. Called by Timer Drivers in order to register + * a Timer to the Timer Library. The registration order determines + * the Timer Number used in tlib_open() to identify a specific + * Timer. + */ +extern int tlib_dev_reg(struct tlib_dev *newdev); + +/* Allocate a Timer. + * + * A Timer handle is returned identifying the timer in later calls. + */ +extern void *tlib_open(int timer_no); + +/* Close Timer */ +extern void tlib_close(void *hand); + +/* Returns Number of Timers currently registered to Timer Library */ +extern int tlib_ntimer(void); + +static inline void tlib_reset(void *hand) +{ + struct tlib_dev *dev = hand; + + dev->drv->reset(dev); +} +/* Get Frequencies: + * - Base Frequency (unchangable base freq rate of timer, prescaler, clkinput) + * - Current Tick Rate [in multiples of Base Frequency] + */ +static inline void tlib_get_freq( + void *hand, + unsigned int *basefreq, + unsigned int *tickrate) +{ + struct tlib_dev *dev = hand; + + dev->drv->get_freq(dev, basefreq, tickrate); +} + +/* Set current Tick Rate in number of "Base-Frequency ticks" */ +static inline int tlib_set_freq(void *hand, unsigned int tickrate) +{ + struct tlib_dev *dev = hand; + + return dev->drv->set_freq(dev, tickrate); +} + +/* Register ISR at Timer ISR */ +static inline void tlib_irq_unregister(void *hand) +{ + struct tlib_dev *dev = hand; + + if ( dev->isr_func ) { + dev->drv->irq_unreg(dev, dev->isr_func, dev->isr_data); + dev->isr_func = NULL; + } +} + +/* Register ISR at Timer ISR */ +static inline void tlib_irq_register(void *hand, tlib_isr_t func, void *data) +{ + struct tlib_dev *dev = hand; + + /* Unregister previous ISR if installed */ + tlib_irq_unregister(hand); + dev->isr_func = func; + dev->isr_data = data; + dev->drv->irq_reg(dev, func, data); +} + +/* Start Timer, ISRs will be generated if enabled. + * + * once determines if timer should restart (=0) on underflow automatically, + * or stop when underflow is reached (=1). + */ +static inline void tlib_start(void *hand, int once) +{ + struct tlib_dev *dev = hand; + + dev->drv->start(dev, once); +} + +/* Stop Timer, no more ISRs will be generated */ +static inline void tlib_stop(void *hand) +{ + struct tlib_dev *dev = hand; + + dev->drv->stop(dev); +} + +/* Restart/Reload Timer, may be usefull if a Watchdog Timer */ +static inline void tlib_restart(void *hand) +{ + struct tlib_dev *dev = hand; + + dev->drv->restart(dev); +} + +/* Get current counter value (since last tick) */ +static inline void tlib_get_counter(void *hand, unsigned int *counter) +{ + struct tlib_dev *dev = hand; + + dev->drv->get_counter(dev, counter); +} + +/* Do a custom operation */ +static inline void tlib_custom(void *hand, int cmd, void *arg) +{ + struct tlib_dev *dev = hand; + + dev->drv->custom(dev, cmd, arg); +} + +static inline int tlib_interrupt_pending(void *hand, int ack) +{ + struct tlib_dev *dev = hand; + + return dev->drv->int_pend(dev, ack); +} + +#ifdef __cplusplus +} +#endif + +#endif |