Rename time_t to mtime_t.
[bertos.git] / drv / buzzer.c
1 /*!
2  * \file
3  * <!--
4  * Copyright 2003, 2004 Develer S.r.l. (http://www.develer.com/)
5  * Copyright 1999, 2003 Bernardo Innocenti <bernie@develer.com>
6  * This file is part of DevLib - See devlib/README for information.
7  * -->
8  *
9  * \version $Id$
10  *
11  * \brief Buzzer driver (implementation)
12  *
13  * \version $Id$
14  * \author Bernardo Innocenti <bernie@develer.com>
15  */
16
17 /*#*
18  *#* $Log$
19  *#* Revision 1.11  2004/12/08 09:11:53  bernie
20  *#* Rename time_t to mtime_t.
21  *#*
22  *#* Revision 1.10  2004/10/03 18:38:51  bernie
23  *#* Add missing AVR header; Fix header.
24  *#*
25  *#* Revision 1.9  2004/09/14 21:01:25  bernie
26  *#* Use new AVR port pin names.
27  *#*
28  *#* Revision 1.8  2004/08/25 14:12:08  rasky
29  *#* Aggiornato il comment block dei log RCS
30  *#*
31  *#* Revision 1.7  2004/08/24 16:53:43  bernie
32  *#* Add missing headers.
33  *#*
34  *#* Revision 1.6  2004/06/07 18:10:06  aleph
35  *#* Remove free pool of timers; use user-provided Timer structure instead
36  *#*
37  *#* Revision 1.5  2004/06/07 15:54:23  aleph
38  *#* Update to new event.h naming
39  *#*
40  *#* Revision 1.4  2004/06/06 16:09:22  bernie
41  *#* Reformat (from project_ks).
42  *#*
43  *#* Revision 1.3  2004/06/03 11:27:09  bernie
44  *#* Add dual-license information.
45  *#*
46  *#* Revision 1.2  2004/05/23 18:21:53  bernie
47  *#* Trim CVS logs and cleanup header info.
48  *#*
49  *#*/
50
51 #include "buzzer.h"
52
53 #include <drv/timer.h>
54 #include <kern/event.h>
55 #include <debug.h>
56 #include <hw.h>
57 #include <arch_config.h>
58
59
60 #if (ARCH & ARCH_EMUL)
61
62         int Emul_IsBuzzerOn(void);
63         void Emul_BuzzerOn(void);
64         void Emul_BuzzerOff(void);
65         void Emul_BuzzerInit(void);
66
67         #define IS_BUZZER_ON  (Emul_IsBuzzerOn())
68         #define BUZZER_ON     (Emul_BuzzerOn())
69         #define BUZZER_OFF    (Emul_BuzzerOff())
70         #define BUZZER_INIT   (Emul_BuzzerInit())
71
72 #elif defined(__AVR__)
73
74         #include <avr/io.h>
75
76         #define IS_BUZZER_ON  (PORTG & BV(PG0))
77
78         /*!
79          * Buzzer manipulation macros
80          *
81          * \note Some PORTG functions are being used from
82          *       interrupt code, so we must be careful to
83          *       avoid race conditions.
84          */
85         #define BUZZER_ON \
86         do { \
87                 cpuflags_t _flags; \
88                 DISABLE_IRQSAVE(_flags); \
89                 PORTG |= BV(PG0); \
90                 ENABLE_IRQRESTORE(_flags); \
91         } while (0)
92
93         #define BUZZER_OFF \
94         do { \
95                 cpuflags_t _flags; \
96                 DISABLE_IRQSAVE(_flags); \
97                 PORTG &= ~BV(PG0); \
98                 ENABLE_IRQRESTORE(_flags); \
99         } while (0)
100
101         #define BUZZER_INIT \
102         do { \
103                 cpuflags_t _flags; \
104                 DISABLE_IRQSAVE(_flags); \
105                 PORTG &= ~BV(PG0); \
106                 DDRG |= BV(PG0); \
107                 ENABLE_IRQRESTORE(_flags); \
108         } while (0)
109
110 #elif defined(__IAR_SYSTEMS_ICC) || defined(__IAR_SYSTEMS_ICC__) /* 80C196 */
111
112         #define IS_BUZZER_ON  (cpld->Buzzer & 1)
113         #define BUZZER_ON     (cpld->Buzzer = 1)
114         #define BUZZER_OFF    (cpld->Buzzer = 0)
115         #define BUZZER_INIT   (cpld->Buzzer = 0)
116
117 #endif /* ARCH, __AVR__, __IAR_SYSTEM_ICC */
118
119
120 /* Local vars */
121 static Timer buz_timer;
122 static bool buz_timer_running;
123 static mtime_t buz_repeat_interval;
124 static mtime_t buz_repeat_duration;
125
126
127 /*!
128  * Turn off buzzer, called by software timer
129  */
130 static void buz_softint(void)
131 {
132         if (IS_BUZZER_ON)
133         {
134                 BUZZER_OFF;
135                 if (buz_repeat_interval)
136                 {
137                         /* Wait for interval time */
138                         buz_timer.delay = buz_repeat_interval;
139                         timer_add(&buz_timer);
140                 }
141                 else
142                         buz_timer_running = false;
143         }
144         else if (buz_repeat_interval)
145         {
146                 /* Wait for beep time */
147                 BUZZER_ON;
148                 buz_timer.delay = buz_repeat_duration;
149                 timer_add(&buz_timer);
150         }
151         else
152                 buz_timer_running = false;
153 }
154
155
156 /*!
157  * Beep for the specified ms time
158  */
159 void buz_beep(mtime_t time)
160 {
161         cpuflags_t flags;
162
163         /* Remove the software interrupt if it was already queued */
164         DISABLE_IRQSAVE(flags);
165         if (buz_timer_running)
166                 timer_abort(&buz_timer);
167
168         /* Turn on buzzer */
169         BUZZER_ON;
170
171         /* Add software interrupt to turn the buzzer off later */
172         buz_timer_running = true;
173         buz_timer.delay = time;
174         timer_add(&buz_timer);
175
176         ENABLE_IRQRESTORE(flags);
177 }
178
179
180 /*!
181  * Start buzzer repetition
182  */
183 void buz_repeat_start(mtime_t duration, mtime_t interval)
184 {
185         buz_repeat_interval = interval;
186         buz_repeat_duration = duration;
187         buz_beep(duration);
188 }
189
190
191 /*!
192  * Stop buzzer repetition
193  */
194 void buz_repeat_stop(void)
195 {
196         cpuflags_t flags;
197         DISABLE_IRQSAVE(flags);
198
199         /* Remove the software interrupt if it was already queued */
200         if (buz_timer_running)
201         {
202                 timer_abort(&buz_timer);
203                 buz_timer_running = false;
204         }
205
206         buz_repeat_interval = 0;
207         BUZZER_OFF;
208
209         ENABLE_IRQRESTORE(flags);
210 }
211
212
213 /*!
214  * Initialize buzzer
215  */
216 void buz_init(void)
217 {
218         BUZZER_INIT;
219
220         /* Inizializza software interrupt */
221         event_initSoftInt(&buz_timer.expire, (Hook)buz_softint, 0);
222 }