use callout instead of scheduler
[protos/xbee-avr.git] / beep.c
1 /*
2  * Copyright (c) 2011, Olivier MATZ <zer0@droids-corp.org>
3  * All rights reserved.
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  *     * Redistributions of source code must retain the above copyright
8  *       notice, this list of conditions and the following disclaimer.
9  *     * Redistributions in binary form must reproduce the above copyright
10  *       notice, this list of conditions and the following disclaimer in the
11  *       documentation and/or other materials provided with the distribution.
12  *     * Neither the name of the University of California, Berkeley nor the
13  *       names of its contributors may be used to endorse or promote products
14  *       derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #include <stdint.h>
29 #include <stdio.h>
30
31 #include <aversive.h>
32 #include <aversive/wait.h>
33
34 #include <cirbuf.h>
35
36 #include "main.h"
37
38 /* 100 ms */
39 #define BEEP_PERIOD_MS 100
40
41 static struct cirbuf beep_fifo;
42 static char beep_fifo_buf[16];
43 volatile uint8_t beep_mask = 1; /* init beep */
44
45 union beep_t {
46         uint8_t u08;
47         struct {
48                 uint8_t tone:2;
49                 uint8_t len:3;
50                 uint8_t pause:3;
51         };
52 };
53 static volatile union beep_t current_beep;
54
55 /* called by the scheduler */
56 static void beep_cb(struct callout_mgr *cm, struct callout *tim, void *arg)
57 {
58         (void)arg;
59
60         beep_mask = 0;
61         if (current_beep.len == 0 && current_beep.pause == 0) {
62                 if (CIRBUF_GET_LEN(&beep_fifo) == 0)
63                         goto reschedule;
64
65                 current_beep.u08 = cirbuf_get_head(&beep_fifo);
66                 cirbuf_del_head(&beep_fifo);
67         }
68
69         if (current_beep.len > 0) {
70                 current_beep.len --;
71                 switch (current_beep.tone) {
72                         case 0: beep_mask = 1; break;
73                         case 1: beep_mask = 2; break;
74                         case 2: beep_mask = 4; break;
75                         case 3: beep_mask = 8; break;
76                         default: break;
77                 }
78                 goto reschedule;
79         }
80
81         if (current_beep.pause > 0) {
82                 current_beep.pause --;
83         }
84
85  reschedule:
86         callout_reschedule(cm, tim, BEEP_PERIOD_MS);
87 }
88
89 void beep(uint8_t tone, uint8_t len, uint8_t pause)
90 {
91         uint8_t flags;
92         union beep_t b;
93
94         b.tone = tone;
95         b.len = len;
96         b.pause = pause;
97         IRQ_LOCK(flags);
98         cirbuf_add_tail(&beep_fifo, b.u08);
99         IRQ_UNLOCK(flags);
100 }
101
102 void beep_init(void)
103 {
104         cirbuf_init(&beep_fifo, beep_fifo_buf, 0, sizeof(beep_fifo_buf));
105         callout_init(&xbeeboard.beep_timer, beep_cb, NULL, BEEP_PRIO);
106         callout_schedule(&xbeeboard.intr_cm, &xbeeboard.beep_timer,
107                 BEEP_PERIOD_MS);
108 }