4 * Copyright (C) 1999,2003 Bernardo Innocenti <bernie@develer.com>
5 * Copyright (C) 2003 Develer S.r.l. (http://www.develer.com/)
11 * \author Bernardo Innocenti <bernie@develer.com>
13 * \brief Buzzer driver
18 * Revision 1.1 2004/05/23 18:10:11 bernie
19 * Import drv/ modules.
21 * Revision 1.5 2004/04/04 17:44:51 aleph
22 * Move event.h from mware to kern dir
24 * Revision 1.4 2004/03/24 15:03:45 bernie
25 * Use explicit include paths; clean Doxygen comments
27 * Revision 1.3 2004/03/03 18:27:44 bernie
28 * Fixed race conds with IRQ when fiddling with I/O ports
30 * Revision 1.2 2003/12/18 18:15:24 aleph
31 * Use new IRQ disable/enable reentrant macros
33 * Revision 1.1 2003/12/13 23:53:37 aleph
42 #include <kern/event.h>
45 #if (ARCH & ARCH_EMUL)
47 int Emul_IsBuzzerOn(void);
48 void Emul_BuzzerOn(void);
49 void Emul_BuzzerOff(void);
50 void Emul_BuzzerInit(void);
52 # define IS_BUZZER_ON (Emul_IsBuzzerOn())
53 # define BUZZER_ON (Emul_BuzzerOn())
54 # define BUZZER_OFF (Emul_BuzzerOff())
55 # define BUZZER_INIT (Emul_BuzzerInit())
57 #elif defined(__AVR__)
59 # define IS_BUZZER_ON (PORTG & BV(PORTG0))
62 * Buzzer manipulation macros
64 * \note Some PORTG functions are being used from
65 * interrupt code, so we must be careful to
66 * avoid race conditions.
71 DISABLE_IRQSAVE(_flags); \
72 PORTG |= BV(PORTG0); \
73 ENABLE_IRQRESTORE(_flags); \
79 DISABLE_IRQSAVE(_flags); \
80 PORTG &= ~BV(PORTG0); \
81 ENABLE_IRQRESTORE(_flags); \
84 # define BUZZER_INIT \
87 DISABLE_IRQSAVE(_flags); \
88 PORTG &= ~BV(PORTG0); \
90 ENABLE_IRQRESTORE(_flags); \
93 #elif defined(__IAR_SYSTEMS_ICC) || defined(__IAR_SYSTEMS_ICC__) /* 80C196 */
95 # define IS_BUZZER_ON (cpld->Buzzer & 1)
96 # define BUZZER_ON (cpld->Buzzer = 1)
97 # define BUZZER_OFF (cpld->Buzzer = 0)
98 # define BUZZER_INIT (cpld->Buzzer = 0)
100 #endif /* ARCH, __AVR__, __IAR_SYSTEM_ICC */
104 static Timer *buz_timer;
105 static bool buz_timer_running;
106 static time_t buz_repeat_interval;
107 static time_t buz_repeat_duration;
111 * Turn off buzzer, called by software timer
113 static void buz_softint(void)
118 if (buz_repeat_interval)
120 /* Wait for interval time */
121 buz_timer->delay = buz_repeat_interval;
122 timer_add(buz_timer);
125 buz_timer_running = false;
127 else if (buz_repeat_interval)
129 /* Wait for beep time */
131 buz_timer->delay = buz_repeat_duration;
132 timer_add(buz_timer);
135 buz_timer_running = false;
140 * Beep for the specified ms time
142 void buz_beep(time_t time)
146 /* Remove the software interrupt if it was already queued */
147 DISABLE_IRQSAVE(flags);
148 if (buz_timer_running)
149 timer_abort(buz_timer);
154 /* Add software interrupt to turn the buzzer off later */
155 buz_timer_running = true;
156 buz_timer->delay = time;
157 timer_add(buz_timer);
159 ENABLE_IRQRESTORE(flags);
164 * Start buzzer repetition
166 void buz_repeat_start(time_t duration, time_t interval)
168 buz_repeat_interval = interval;
169 buz_repeat_duration = duration;
175 * Stop buzzer repetition
177 void buz_repeat_stop(void)
180 DISABLE_IRQSAVE(flags);
182 /* Remove the software interrupt if it was already queued */
183 if (buz_timer_running)
185 timer_abort(buz_timer);
186 buz_timer_running = false;
189 buz_repeat_interval = 0;
192 ENABLE_IRQRESTORE(flags);
203 /* Inizializza software interrupt */
204 buz_timer = timer_new();
205 ASSERT(buz_timer != NULL);
206 INITEVENT_INT(&buz_timer->expire, (Hook)buz_softint, 0);