add a complete rc_proto stack (not tested)
[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 static struct callout beep_timer;
46
47 union beep_t {
48         uint8_t u08;
49         struct {
50                 uint8_t tone:2;
51                 uint8_t len:3;
52                 uint8_t pause:3;
53         };
54 };
55 static volatile union beep_t current_beep;
56
57 /* called by the scheduler */
58 static void beep_cb(struct callout_mgr *cm, struct callout *tim, void *arg)
59 {
60         (void)arg;
61
62         beep_mask = 0;
63         if (current_beep.len == 0 && current_beep.pause == 0) {
64                 if (CIRBUF_GET_LEN(&beep_fifo) == 0)
65                         goto reschedule;
66
67                 current_beep.u08 = cirbuf_get_head(&beep_fifo);
68                 cirbuf_del_head(&beep_fifo);
69         }
70
71         if (current_beep.len > 0) {
72                 current_beep.len --;
73                 switch (current_beep.tone) {
74                         case 0: beep_mask = 1; break;
75                         case 1: beep_mask = 2; break;
76                         case 2: beep_mask = 4; break;
77                         case 3: beep_mask = 8; break;
78                         default: break;
79                 }
80                 goto reschedule;
81         }
82
83         if (current_beep.pause > 0) {
84                 current_beep.pause --;
85         }
86
87  reschedule:
88         callout_reschedule(cm, tim, BEEP_PERIOD_MS);
89 }
90
91 void beep(uint8_t tone, uint8_t len, uint8_t pause)
92 {
93         uint8_t flags;
94         union beep_t b;
95
96         b.tone = tone;
97         b.len = len;
98         b.pause = pause;
99         IRQ_LOCK(flags);
100         cirbuf_add_tail(&beep_fifo, b.u08);
101         IRQ_UNLOCK(flags);
102 }
103
104 void beep_init(void)
105 {
106         cirbuf_init(&beep_fifo, beep_fifo_buf, 0, sizeof(beep_fifo_buf));
107         callout_init(&beep_timer, beep_cb, NULL, BEEP_PRIO);
108         callout_schedule(&xbeeboard.intr_cm, &beep_timer, BEEP_PERIOD_MS);
109 }