2 * Copyright Droids Corporation (2007)
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.
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.
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
18 * Revision : $Id: scheduler.h,v 1.8.4.11 2009-05-18 12:30:36 zer0 Exp $
22 /* Olivier MATZ <zer0@droids-corp.org>
23 * Interface of the SCHEDULER Module
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.
34 * Functions with a high priority value will be call before others
37 * This module uses Timer 0
46 #ifdef CONFIG_MODULE_SCHEDULER_USE_TIMERS
48 #endif /* CONFIG_MODULE_SCHEDULER_USE_TIMERS */
50 #include <scheduler_config.h>
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()
57 #define SCHEDULER_TIMER_BITS 16
59 #define SCHEDULER_TIMER_BITS 8
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()
66 #define SCHEDULER_TIMER_BITS 16
68 #define SCHEDULER_TIMER_BITS 8
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()
75 #define SCHEDULER_TIMER_BITS 16
77 #define SCHEDULER_TIMER_BITS 8
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()
84 #define SCHEDULER_TIMER_BITS 16
86 #define SCHEDULER_TIMER_BITS 8
90 #error "Bad SCHEDULER_TIMER_NUM value in config file"
93 #endif /* CONFIG_MODULE_SCHEDULER_USE_TIMERS */
95 #ifdef CONFIG_MODULE_SCHEDULER_TIMER0
96 #define SCHEDULER_TIMER_BITS 8
97 #endif /* CONFIG_MODULE_SCHEDULER_TIMER0 */
99 #ifndef CONFIG_MODULE_SCHEDULER_MANUAL
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) )
106 #define TIMER_UNIT_FLOAT ( 65536000000.0 / (double)(CONFIG_QUARTZ) )
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.
114 #define SCHEDULER_UNIT_FLOAT ( TIMER_UNIT_FLOAT * (double)SCHEDULER_CLOCK_PRESCALER )
115 #define SCHEDULER_UNIT ( (unsigned long) SCHEDULER_UNIT_FLOAT )
117 #endif /* ! CONFIG_MODULE_SCHEDULER_MANUAL */
121 #define SCHEDULER_PERIODICAL 0
122 #define SCHEDULER_SINGLE 1
124 #define SCHEDULER_DEFAULT_PRIORITY 128
127 /** Initialisation of the module */
128 void scheduler_init(void);
130 /** dump all loaded events */
131 void scheduler_dump_events(void);
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.
138 int8_t scheduler_add_event(uint8_t unicity, void (*f)(void *), void * data, uint16_t period, uint8_t priority);
142 * Add a single event to the event table, specifying the priority
144 static inline int8_t scheduler_add_single_event_priority(void (*f)(void *), void * data, uint16_t period, uint8_t priority)
146 return scheduler_add_event(SCHEDULER_SINGLE, f, data, period, priority);
150 * Add a periodical event to the event table, specifying the priority
152 static inline int8_t scheduler_add_periodical_event_priority(void (*f)(void *), void * data, uint16_t period, uint8_t priority)
154 return scheduler_add_event(SCHEDULER_PERIODICAL, f, data, period, priority);
158 * Add a single event to the event table, with the default priority
160 static inline int8_t scheduler_add_single_event(void (*f)(void *), void * data, uint16_t period)
162 return scheduler_add_event(SCHEDULER_SINGLE, f, data, period, SCHEDULER_DEFAULT_PRIORITY);
166 * Add a periodical event to the event table, with the default priority
168 static inline int8_t scheduler_add_periodical_event(void (*f)(void *), void * data, uint16_t period)
170 return scheduler_add_event(SCHEDULER_PERIODICAL, f, data, period, SCHEDULER_DEFAULT_PRIORITY);
174 * Dels an event from the table by its ID. If there is no event,
177 int8_t scheduler_del_event(int8_t num);
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);
188 * Temporarily disable scheduler events. You may loose precision in
189 * events schedule. It returns the current priority of the scheduler.
191 uint8_t scheduler_disable_save(void);
194 * Re-enable scheduler after a call to scheduler_disable_save().
196 void scheduler_enable_restore(uint8_t old_prio);