Push interrupt protection inside hw module.
[bertos.git] / drv / buzzer.c
1 /*!
2  * \file
3  * <!--
4  * Copyright 2003, 2004, 2005 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 README.devlib 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  * \author Francesco Sacchi <batt@develer.com>
16  */
17
18 /*#*
19  *#* $Log$
20  *#* Revision 1.17  2006/02/10 12:30:18  bernie
21  *#* Push interrupt protection inside hw module.
22  *#*
23  *#* Revision 1.16  2005/11/04 16:19:33  bernie
24  *#* buz_init(): Restore IRQ protection as in project_bko.
25  *#*
26  *#* Revision 1.15  2005/06/27 21:25:50  bernie
27  *#* Modularize hardware access; Port to new timer interface.
28  *#*
29  *#* Revision 1.14  2005/04/11 19:10:27  bernie
30  *#* Include top-level headers from cfg/ subdir.
31  *#*
32  *#* Revision 1.13  2005/02/18 11:20:15  bernie
33  *#* Use mware/event.h; Update copyright info.
34  *#*
35  *#* Revision 1.12  2004/12/13 12:07:06  bernie
36  *#* DISABLE_IRQSAVE/ENABLE_IRQRESTORE: Convert to IRQ_SAVE_DISABLE/IRQ_RESTORE.
37  *#*
38  *#* Revision 1.11  2004/12/08 09:11:53  bernie
39  *#* Rename time_t to mtime_t.
40  *#*
41  *#* Revision 1.10  2004/10/03 18:38:51  bernie
42  *#* Add missing AVR header; Fix header.
43  *#*
44  *#* Revision 1.9  2004/09/14 21:01:25  bernie
45  *#* Use new AVR port pin names.
46  *#*/
47
48 #include "buzzer.h"
49
50 #include <hw_buzzer.h>
51 #include <drv/timer.h>
52
53 #include <mware/event.h>
54
55 #include <cfg/debug.h>
56
57
58 /* Local vars */
59 static Timer buz_timer;
60 static bool buz_timer_running;
61 static mtime_t buz_repeat_interval;
62 static mtime_t buz_repeat_duration;
63
64
65 /*!
66  * Turn off buzzer, called by software timer
67  */
68 static void buz_softint(void)
69 {
70         if (IS_BUZZER_ON)
71         {
72                 BUZZER_OFF;
73                 if (buz_repeat_interval)
74                 {
75                         /* Wait for interval time */
76                         timer_setDelay(&buz_timer, ms_to_ticks(buz_repeat_interval));
77                         timer_add(&buz_timer);
78                 }
79                 else
80                         buz_timer_running = false;
81         }
82         else if (buz_repeat_interval)
83         {
84                 /* Wait for beep time */
85                 BUZZER_ON;
86                 timer_setDelay(&buz_timer, ms_to_ticks(buz_repeat_duration));
87                 timer_add(&buz_timer);
88         }
89         else
90                 buz_timer_running = false;
91 }
92
93
94 /*!
95  * Beep for the specified ms time
96  */
97 void buz_beep(mtime_t time)
98 {
99         cpuflags_t flags;
100         IRQ_SAVE_DISABLE(flags);
101
102         /* Remove the software interrupt if it was already queued */
103         if (buz_timer_running)
104                 timer_abort(&buz_timer);
105
106         /* Turn on buzzer */
107         BUZZER_ON;
108
109         /* Add software interrupt to turn the buzzer off later */
110         buz_timer_running = true;
111         timer_setDelay(&buz_timer, ms_to_ticks(time));
112         timer_add(&buz_timer);
113
114         IRQ_RESTORE(flags);
115 }
116
117
118 /*!
119  * Start buzzer repetition
120  */
121 void buz_repeat_start(mtime_t duration, mtime_t interval)
122 {
123         buz_repeat_interval = interval;
124         buz_repeat_duration = duration;
125         buz_beep(duration);
126 }
127
128
129 /*!
130  * Stop buzzer repetition
131  */
132 void buz_repeat_stop(void)
133 {
134         cpuflags_t flags;
135         IRQ_SAVE_DISABLE(flags);
136
137         /* Remove the software interrupt if it was already queued */
138         if (buz_timer_running)
139         {
140                 timer_abort(&buz_timer);
141                 buz_timer_running = false;
142         }
143
144         buz_repeat_interval = 0;
145         BUZZER_OFF;
146
147         IRQ_RESTORE(flags);
148 }
149
150
151 /*!
152  * Initialize buzzer.
153  */
154 void buz_init(void)
155 {
156         BUZZER_HW_INIT;
157
158         /* Init software interrupt. */
159         timer_set_event_softint(&buz_timer, (Hook)buz_softint, 0);
160 }