Contiki 2.5
beep.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2008 Swedish Institute of Computer Science
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in
12  * the documentation and/or other materials provided with the
13  * distribution.
14  * * Neither the name of the copyright holders nor the names of
15  * contributors may be used to endorse or promote products derived
16  * from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */
30 /**
31  * \file
32  *
33  * \brief
34  * This file implements a beep function to emit a beep sound from Raven's
35  * speaker. Also polyphonic ringtones.
36  *
37  * \author
38  * Mike Vidales mavida404@gmail.com
39  * David Kopf dak664@embarqmail.com
40  *
41  */
42 
43 
44 #include "beep.h"
45 #include "key.h"
46 #include <stdlib.h>
47 #include "util/delay.h"
48 
49 /**
50  * \addtogroup lcd
51  * \{
52 */
53 /*---------------------------------------------------------------------------*/
54 
55 /**
56  * \brief Emits a beep from the Raven's buzzer. This routine simply toggles a port pin
57  * at an audio frequency, which causes a tone to be emitted from the Raven's speaker.
58  * The beep consists of two tones at two different frequencies. At the end, the beeper
59  * port pin is kept low, which causes the speaker amplifier to shut down.
60 */
61 void
62 beep(void)
63 {
64  uint8_t i;
65  volatile uint8_t j;
66 
67  /* Turn on the power to the speaker. */
68  ENTER_DDR |= (1 << PE7);
69  ENTER_PUR |= (1 << PE7);
70 
71  /* Setup port pin */
72  BEEP_DDR |= (1 << BEEP_BIT);
73 
74  for (i=0;i<100;i++){
75  /* Toggle port pin */
76  BEEP_PIN |= (1 << BEEP_BIT);
77  /* Delay loop */
78  for (j=0;j<0xff;j++)
79  ;
80  }
81 
82  for (i=0;i<100;i++){
83  /* Toggle port pin */
84  BEEP_PIN |= (1 << BEEP_BIT);
85  /* Delay loop */
86  for (j=0;j<0xa0;j++)
87  ;
88  }
89 
90  /* Turn off speaker */
91  BEEP_PORT &= ~(1 << BEEP_BIT);
92  ENTER_PUR &= ~(1 << PE7);
93 }
94 
95 /*---------------------------------------------------------------------------*/
96 /**
97  * \brief Play polyphonic tune using buzzer. An 8 bit timer generates interrupts
98  * that flip the BEEP pin at the selected frequencies.
99  * On exit the beeper port pin is set low to shut down the speaker amplifier.
100 */
101 /* Base interrupts per second, and interrupts for each note */
102 //#define BASE 31250
103 #define BASE 31250/2 //up one octave
104 #define NONE 0
105 #define C4 BASE/262
106 #define CS4 BASE/277
107 #define D4 BASE/294
108 #define DS4 BASE/311
109 #define E4 BASE/330
110 #define F4 BASE/349
111 #define FS4 BASE/370
112 #define G4 BASE/392
113 #define GS4 BASE/415
114 #define A4 BASE/440
115 #define AS4 BASE/466
116 #define B4 BASE/494
117 #define C5 BASE/523
118 #define CS5 BASE/554
119 #define D5 BASE/587
120 #define DS5 BASE/622
121 #define E5 BASE/659
122 #define F5 BASE/698
123 #define FS5 BASE/740
124 #define G5 BASE/784
125 #define GS5 BASE/831
126 #define A5 BASE/880
127 #define AS5 BASE/932
128 
129 /* Tone reference length and internote gap, milliseconds */
130 #define TONE_LENGTH 60
131 #define TONE_GAP 20
132 
133 
134 static uint8_t tuneindex=0;
135 static uint8_t pictures[] PROGMEM = {G4,4, F4,4, AS4,4, C5,2, F5,2, D5,4, C5,2, F5,2, D5,4, AS4,4, C5,4, G4,4, F4,4, 0xff};
136 static uint8_t axel[] PROGMEM = {FS4,2, NONE,2, A4,3, FS4,2, FS4,1, B4,2, FS4,2, E4,2, FS4,2, NONE,2, CS5,3, FS4,2, FS4,1, D5,2, CS5,2, A4,2, FS4,2, CS5,2, FS5,2, FS4,1, E4,2, E4,1, CS4,2, GS4,2, FS4,6, 0xff};
137 static uint8_t sandman1[] PROGMEM = {F4,2, G4,2, B4,4, A4,10, B4,2, B4,2, A4,2, B4,12, 0xff};
138 static uint8_t sandman2[] PROGMEM = {C4,2, E4,2, G4,2, B4,2, A4,2, G4,2, E4,2, C4,2, D4,2, F4,2, A4,2, C5,2, B4,8, 0xff};
139 static uint8_t furelise[] PROGMEM = {E5,1, DS5,1, E5,1, DS5,1, E5,1, B4,1, D5,1, E5,1, A4,2, NONE,1, C4,1, E4,1, A4,1, B4,2, NONE,1, E4,1, GS4,1, B4,1, C5,2, 0xff};
140 
141 static volatile uint8_t icnt,tone;
142 
143 #include <avr/interrupt.h>
144 ISR(TIMER0_OVF_vect)
145 {
146  if (tone == NONE) icnt = 0;
147  else if (icnt++ >= tone)
148  {
149  BEEP_PIN |= (1 << BEEP_BIT);
150  icnt = 0;
151  }
152 }
153 
154 void play_ringtone(void)
155 {
156 uint8_t i,*noteptr;
157 
158  /* What's next on the playlist? */
159  switch (tuneindex++) {
160  case 1 :beep();return;
161  case 2 :noteptr=sandman1;break;
162  case 3 :noteptr=furelise;break;
163  case 4 :noteptr=sandman2;break;
164  case 5 :noteptr=axel;break;
165  default:noteptr=pictures;tuneindex=1;break;
166  }
167 
168  /* Turn on the power to the speaker. */
169  ENTER_DDR |= (1 << PE7);
170  ENTER_PUR |= (1 << PE7);
171 
172  /* Setup port pin */
173  BEEP_DDR |= (1 << BEEP_BIT);
174 
175  /* Start with no tone */
176  icnt = 0;
177  tone = NONE;
178 
179  /* Clock 8 bit timer at maximum frequency (CS0=1), interrupt overflow */
180  /* 8MHz / 256 = 31250 interrupts per second */
181  TCCR0A |= _BV(CS00);
182  TCNT0 = 0;
183  TIMSK0 |= _BV(TOIE0);
184 
185  /* Play all the notes */
186  for (;;) {
187  tone=pgm_read_byte(noteptr++);
188  if (tone==0xff) break;
189  for (i = pgm_read_byte(noteptr++);i > 0; i--) _delay_us(1000UL*TONE_LENGTH);
190  tone = NONE;_delay_us(1000UL*TONE_GAP);
191  }
192 
193  /* Turn off interrupts and speaker */
194  TIMSK0 &= ~_BV(TOIE0);
195  BEEP_PORT &= ~(1 << BEEP_BIT);
196  ENTER_PUR &= ~(1 << PE7);
197 }
198 /** \} */