Use mware/event.h; Update copyright info.
[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  */
16
17 /*#*
18  *#* $Log$
19  *#* Revision 1.13  2005/02/18 11:20:15  bernie
20  *#* Use mware/event.h; Update copyright info.
21  *#*
22  *#* Revision 1.12  2004/12/13 12:07:06  bernie
23  *#* DISABLE_IRQSAVE/ENABLE_IRQRESTORE: Convert to IRQ_SAVE_DISABLE/IRQ_RESTORE.
24  *#*
25  *#* Revision 1.11  2004/12/08 09:11:53  bernie
26  *#* Rename time_t to mtime_t.
27  *#*
28  *#* Revision 1.10  2004/10/03 18:38:51  bernie
29  *#* Add missing AVR header; Fix header.
30  *#*
31  *#* Revision 1.9  2004/09/14 21:01:25  bernie
32  *#* Use new AVR port pin names.
33  *#*/
34
35 #include "buzzer.h"
36
37 #include <drv/timer.h>
38 #include <mware/event.h>
39
40 #include <macros.h> /* BV() */
41 #include <debug.h>
42 #include <hw.h>
43 #include <arch_config.h>
44
45
46 #if (ARCH & ARCH_EMUL)
47
48         int Emul_IsBuzzerOn(void);
49         void Emul_BuzzerOn(void);
50         void Emul_BuzzerOff(void);
51         void Emul_BuzzerInit(void);
52
53         #define IS_BUZZER_ON  (Emul_IsBuzzerOn())
54         #define BUZZER_ON     (Emul_BuzzerOn())
55         #define BUZZER_OFF    (Emul_BuzzerOff())
56         #define BUZZER_INIT   (Emul_BuzzerInit())
57
58 #elif defined(__AVR__)
59
60         #include <avr/io.h>
61
62         #define IS_BUZZER_ON  (PORTG & BV(PG0))
63
64         /*!
65          * \name Buzzer manipulation macros.
66          *
67          * \note Some PORTG functions are being used from
68          *       interrupt code, so we must be careful to
69          *       avoid race conditions.
70          * \{
71          */
72         #define BUZZER_ON ATOMIC(PORTG |= BV(PG0))
73         #define BUZZER_OFF ATOMIC(PORTG &= ~BV(PG0))
74         #define BUZZER_INIT ATOMIC(PORTG &= ~BV(PG0); DDRG |= BV(PG0);)
75         /*\}*/
76
77 #elif defined(__IAR_SYSTEMS_ICC) || defined(__IAR_SYSTEMS_ICC__) /* 80C196 */
78
79         #define IS_BUZZER_ON  (cpld->Buzzer & 1)
80         #define BUZZER_ON     (cpld->Buzzer = 1)
81         #define BUZZER_OFF    (cpld->Buzzer = 0)
82         #define BUZZER_INIT   (cpld->Buzzer = 0)
83
84 #endif /* ARCH, __AVR__, __IAR_SYSTEM_ICC */
85
86
87 /* Local vars */
88 static Timer buz_timer;
89 static bool buz_timer_running;
90 static mtime_t buz_repeat_interval;
91 static mtime_t buz_repeat_duration;
92
93
94 /*!
95  * Turn off buzzer, called by software timer
96  */
97 static void buz_softint(void)
98 {
99         if (IS_BUZZER_ON)
100         {
101                 BUZZER_OFF;
102                 if (buz_repeat_interval)
103                 {
104                         /* Wait for interval time */
105                         buz_timer.delay = buz_repeat_interval;
106                         timer_add(&buz_timer);
107                 }
108                 else
109                         buz_timer_running = false;
110         }
111         else if (buz_repeat_interval)
112         {
113                 /* Wait for beep time */
114                 BUZZER_ON;
115                 buz_timer.delay = buz_repeat_duration;
116                 timer_add(&buz_timer);
117         }
118         else
119                 buz_timer_running = false;
120 }
121
122
123 /*!
124  * Beep for the specified ms time
125  */
126 void buz_beep(mtime_t time)
127 {
128         cpuflags_t flags;
129         IRQ_SAVE_DISABLE(flags);
130
131         /* Remove the software interrupt if it was already queued */
132         if (buz_timer_running)
133                 timer_abort(&buz_timer);
134
135         /* Turn on buzzer */
136         BUZZER_ON;
137
138         /* Add software interrupt to turn the buzzer off later */
139         buz_timer_running = true;
140         buz_timer.delay = time;
141         timer_add(&buz_timer);
142
143         IRQ_RESTORE(flags);
144 }
145
146
147 /*!
148  * Start buzzer repetition
149  */
150 void buz_repeat_start(mtime_t duration, mtime_t interval)
151 {
152         buz_repeat_interval = interval;
153         buz_repeat_duration = duration;
154         buz_beep(duration);
155 }
156
157
158 /*!
159  * Stop buzzer repetition
160  */
161 void buz_repeat_stop(void)
162 {
163         cpuflags_t flags;
164         IRQ_SAVE_DISABLE(flags);
165
166         /* Remove the software interrupt if it was already queued */
167         if (buz_timer_running)
168         {
169                 timer_abort(&buz_timer);
170                 buz_timer_running = false;
171         }
172
173         buz_repeat_interval = 0;
174         BUZZER_OFF;
175
176         IRQ_RESTORE(flags);
177 }
178
179
180 /*!
181  * Initialize buzzer
182  */
183 void buz_init(void)
184 {
185         BUZZER_INIT;
186
187         /* Inizializza software interrupt */
188         event_initSoftInt(&buz_timer.expire, (Hook)buz_softint, 0);
189 }