merge
[aversive.git] / modules / base / scheduler / scheduler.h
1 /*  
2  *  Copyright Droids Corporation (2007)
3  * 
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  *
18  *  Revision : $Id: scheduler.h,v 1.8.4.11 2009-05-18 12:30:36 zer0 Exp $
19  *
20  */
21
22 /* Olivier MATZ <zer0@droids-corp.org>
23  * Interface of the SCHEDULER Module
24  */
25
26 /** \file scheduler.h
27  *
28  * This module provides a function scheduler. You can call
29  * scheduler_add_event for adding a function to the scheduler, and
30  * specifying what interval between each call. During the execution of
31  * the function, interrupts are masked !! So use this module with
32  * caution (small functions) for avoiding problems.
33  *
34  * Functions with a high priority value will be call before others
35  * (default is 128).
36  *
37  * This module uses Timer 0
38  */
39
40
41 #ifndef _SCHEDULER_H_
42 #define _SCHEDULER_H_
43
44 #include <aversive.h>
45
46 #ifdef CONFIG_MODULE_SCHEDULER_USE_TIMERS
47 #include <timer.h>
48 #endif /* CONFIG_MODULE_SCHEDULER_USE_TIMERS */
49
50 #include <scheduler_config.h>
51
52 #ifdef CONFIG_MODULE_SCHEDULER_USE_TIMERS
53 #if SCHEDULER_TIMER_NUM == 0
54 #define SCHEDULER_TIMER_REGISTER()  timer0_register_OV_intr(scheduler_interrupt)
55 #define SCHEDULER_CLOCK_PRESCALER timer0_get_prescaler_div()
56 #ifdef TCNT0H
57 #define SCHEDULER_TIMER_BITS 16
58 #else
59 #define SCHEDULER_TIMER_BITS 8
60 #endif
61
62 #elif SCHEDULER_TIMER_NUM == 1
63 #define SCHEDULER_TIMER_REGISTER()  timer1_register_OV_intr(scheduler_interrupt)
64 #define SCHEDULER_CLOCK_PRESCALER timer1_get_prescaler_div()
65 #ifdef TCNT1H
66 #define SCHEDULER_TIMER_BITS 16
67 #else
68 #define SCHEDULER_TIMER_BITS 8
69 #endif
70
71 #elif SCHEDULER_TIMER_NUM == 2
72 #define SCHEDULER_TIMER_REGISTER()  timer2_register_OV_intr(scheduler_interrupt)
73 #define SCHEDULER_CLOCK_PRESCALER timer2_get_prescaler_div()
74 #ifdef TCNT2H
75 #define SCHEDULER_TIMER_BITS 16
76 #else
77 #define SCHEDULER_TIMER_BITS 8
78 #endif
79
80 #elif SCHEDULER_TIMER_NUM == 3
81 #define SCHEDULER_TIMER_REGISTER()  timer3_register_OV_intr(scheduler_interrupt)
82 #define SCHEDULER_CLOCK_PRESCALER timer3_get_prescaler_div()
83 #ifdef TCNT3H
84 #define SCHEDULER_TIMER_BITS 16
85 #else
86 #define SCHEDULER_TIMER_BITS 8
87 #endif
88
89 #else
90 #error "Bad SCHEDULER_TIMER_NUM value in config file"
91 #endif
92
93 #endif /* CONFIG_MODULE_SCHEDULER_USE_TIMERS */
94
95 #ifdef CONFIG_MODULE_SCHEDULER_TIMER0
96 #define SCHEDULER_TIMER_BITS 8
97 #endif /* CONFIG_MODULE_SCHEDULER_TIMER0 */
98
99 #ifndef CONFIG_MODULE_SCHEDULER_MANUAL
100
101 /** TIME_UNIT is the number of microseconds between each interruption
102  * if the prescaler equals 1 */
103 #if SCHEDULER_TIMER_BITS == 8
104 #define TIMER_UNIT_FLOAT ( 256000000.0 / (double)(CONFIG_QUARTZ) )
105 #else
106 #define TIMER_UNIT_FLOAT ( 65536000000.0 / (double)(CONFIG_QUARTZ) )
107 #endif
108
109 /** SCHEDULER_UNIT is the number of microseconds between each
110  *  scheduler interruption. We can use it like this :
111  *    scheduler_add_periodical_event(f, 1000L/SCHEDULER_UNIT);
112  *  The function f will be called every ms. 
113  */
114 #define SCHEDULER_UNIT_FLOAT ( TIMER_UNIT_FLOAT * (double)SCHEDULER_CLOCK_PRESCALER )
115 #define SCHEDULER_UNIT ( (unsigned long) SCHEDULER_UNIT_FLOAT )
116
117 #endif /* ! CONFIG_MODULE_SCHEDULER_MANUAL */
118
119
120
121 #define SCHEDULER_PERIODICAL 0
122 #define SCHEDULER_SINGLE 1
123
124 #define SCHEDULER_DEFAULT_PRIORITY 128
125
126
127 /** Initialisation of the module */
128 void scheduler_init(void);
129
130 /** dump all loaded events */
131 void scheduler_dump_events(void);
132
133 /** 
134  * Add an event to the event table.
135  * Return the id of the event on succes and -1 on error
136  * You can use static inline funcs below for simpler use.
137  */
138 int8_t scheduler_add_event(uint8_t unicity, void (*f)(void *), void * data, uint16_t period, uint8_t priority);
139
140
141 /** 
142  * Add a single event to the event table, specifying the priority
143  */
144 static inline int8_t scheduler_add_single_event_priority(void (*f)(void *), void * data, uint16_t period, uint8_t priority)
145 {
146         return scheduler_add_event(SCHEDULER_SINGLE, f, data, period, priority);
147 }
148
149 /** 
150  * Add a periodical event to the event table, specifying the priority
151  */
152 static inline int8_t scheduler_add_periodical_event_priority(void (*f)(void *), void * data, uint16_t period, uint8_t priority)
153 {
154         return scheduler_add_event(SCHEDULER_PERIODICAL, f, data, period, priority);
155 }
156
157 /** 
158  * Add a single event to the event table, with the default priority
159  */
160 static inline int8_t scheduler_add_single_event(void (*f)(void *), void * data, uint16_t period)
161 {
162         return scheduler_add_event(SCHEDULER_SINGLE, f, data, period, SCHEDULER_DEFAULT_PRIORITY);
163 }
164
165 /** 
166  * Add a periodical event to the event table, with the default priority
167  */
168 static inline int8_t scheduler_add_periodical_event(void (*f)(void *), void * data, uint16_t period)
169 {
170         return scheduler_add_event(SCHEDULER_PERIODICAL, f, data, period, SCHEDULER_DEFAULT_PRIORITY);
171 }
172
173 /**
174  * Dels an event from the table by its ID. If there is no event,
175  * nothing is done.
176  */
177 int8_t scheduler_del_event(int8_t num);
178
179 /** Function called by the interruption. It is public in case of host
180  *  version, because you have to call it by hand. In AVR version, you
181  *  don't have to do anything with this function, it is called
182  *  automatilcally by the timer interruption, except if
183  *  CONFIG_MODULE_SCHEDULER_MANUAL is defined. In this case you have
184  *  to call it manually too. */
185 void scheduler_interrupt(void);
186
187 /**
188  * Temporarily disable scheduler events. You may loose precision in
189  * events schedule. It returns the current priority of the scheduler.
190  */
191 uint8_t scheduler_disable_save(void);
192
193 /**
194  * Re-enable scheduler after a call to scheduler_disable_save().
195  */
196 void scheduler_enable_restore(uint8_t old_prio);
197
198 #endif