Contiki 2.6
|
00001 /* 00002 * Copyright (c) 2008 Swedish Institute of Computer Science 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions are met: 00007 * 00008 * * Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * * Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in 00012 * the documentation and/or other materials provided with the 00013 * distribution. 00014 * * Neither the name of the copyright holders nor the names of 00015 * contributors may be used to endorse or promote products derived 00016 * from this software without specific prior written permission. 00017 * 00018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00021 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00022 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00028 * POSSIBILITY OF SUCH DAMAGE. 00029 */ 00030 /** 00031 * \file 00032 * 00033 * \brief 00034 * This file implements a beep function to emit a beep sound from Raven's 00035 * speaker. Also polyphonic ringtones. 00036 * 00037 * \author 00038 * Mike Vidales mavida404@gmail.com 00039 * David Kopf dak664@embarqmail.com 00040 * 00041 */ 00042 00043 00044 #include "beep.h" 00045 #include "key.h" 00046 #include <stdlib.h> 00047 #include "util/delay.h" 00048 00049 /** 00050 * \addtogroup lcd 00051 * \{ 00052 */ 00053 /*---------------------------------------------------------------------------*/ 00054 00055 /** 00056 * \brief Emits a beep from the Raven's buzzer. This routine simply toggles a port pin 00057 * at an audio frequency, which causes a tone to be emitted from the Raven's speaker. 00058 * The beep consists of two tones at two different frequencies. At the end, the beeper 00059 * port pin is kept low, which causes the speaker amplifier to shut down. 00060 */ 00061 void 00062 beep(void) 00063 { 00064 uint8_t i; 00065 volatile uint8_t j; 00066 00067 /* Turn on the power to the speaker. */ 00068 ENTER_DDR |= (1 << PE7); 00069 ENTER_PUR |= (1 << PE7); 00070 00071 /* Setup port pin */ 00072 BEEP_DDR |= (1 << BEEP_BIT); 00073 00074 for (i=0;i<100;i++){ 00075 /* Toggle port pin */ 00076 BEEP_PIN |= (1 << BEEP_BIT); 00077 /* Delay loop */ 00078 for (j=0;j<0xff;j++) 00079 ; 00080 } 00081 00082 for (i=0;i<100;i++){ 00083 /* Toggle port pin */ 00084 BEEP_PIN |= (1 << BEEP_BIT); 00085 /* Delay loop */ 00086 for (j=0;j<0xa0;j++) 00087 ; 00088 } 00089 00090 /* Turn off speaker */ 00091 BEEP_PORT &= ~(1 << BEEP_BIT); 00092 ENTER_PUR &= ~(1 << PE7); 00093 } 00094 00095 /*---------------------------------------------------------------------------*/ 00096 /** 00097 * \brief Play polyphonic tune using buzzer. An 8 bit timer generates interrupts 00098 * that flip the BEEP pin at the selected frequencies. 00099 * On exit the beeper port pin is set low to shut down the speaker amplifier. 00100 */ 00101 /* Base interrupts per second, and interrupts for each note */ 00102 //#define BASE 31250 00103 #define BASE 31250/2 //up one octave 00104 #define NONE 0 00105 #define C4 BASE/262 00106 #define CS4 BASE/277 00107 #define D4 BASE/294 00108 #define DS4 BASE/311 00109 #define E4 BASE/330 00110 #define F4 BASE/349 00111 #define FS4 BASE/370 00112 #define G4 BASE/392 00113 #define GS4 BASE/415 00114 #define A4 BASE/440 00115 #define AS4 BASE/466 00116 #define B4 BASE/494 00117 #define C5 BASE/523 00118 #define CS5 BASE/554 00119 #define D5 BASE/587 00120 #define DS5 BASE/622 00121 #define E5 BASE/659 00122 #define F5 BASE/698 00123 #define FS5 BASE/740 00124 #define G5 BASE/784 00125 #define GS5 BASE/831 00126 #define A5 BASE/880 00127 #define AS5 BASE/932 00128 00129 /* Tone reference length and internote gap, milliseconds */ 00130 #define TONE_LENGTH 60 00131 #define TONE_GAP 20 00132 00133 00134 static uint8_t tuneindex=0; 00135 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}; 00136 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}; 00137 static uint8_t sandman1[] PROGMEM = {F4,2, G4,2, B4,4, A4,10, B4,2, B4,2, A4,2, B4,12, 0xff}; 00138 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}; 00139 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}; 00140 00141 static volatile uint8_t icnt,tone; 00142 00143 #include <avr/interrupt.h> 00144 ISR(TIMER0_OVF_vect) 00145 { 00146 if (tone == NONE) icnt = 0; 00147 else if (icnt++ >= tone) 00148 { 00149 BEEP_PIN |= (1 << BEEP_BIT); 00150 icnt = 0; 00151 } 00152 } 00153 00154 void play_ringtone(void) 00155 { 00156 uint8_t i,*noteptr; 00157 00158 /* What's next on the playlist? */ 00159 switch (tuneindex++) { 00160 case 1 :beep();return; 00161 case 2 :noteptr=sandman1;break; 00162 case 3 :noteptr=furelise;break; 00163 case 4 :noteptr=sandman2;break; 00164 case 5 :noteptr=axel;break; 00165 default:noteptr=pictures;tuneindex=1;break; 00166 } 00167 00168 /* Turn on the power to the speaker. */ 00169 ENTER_DDR |= (1 << PE7); 00170 ENTER_PUR |= (1 << PE7); 00171 00172 /* Setup port pin */ 00173 BEEP_DDR |= (1 << BEEP_BIT); 00174 00175 /* Start with no tone */ 00176 icnt = 0; 00177 tone = NONE; 00178 00179 /* Clock 8 bit timer at maximum frequency (CS0=1), interrupt overflow */ 00180 /* 8MHz / 256 = 31250 interrupts per second */ 00181 TCCR0A |= _BV(CS00); 00182 TCNT0 = 0; 00183 TIMSK0 |= _BV(TOIE0); 00184 00185 /* Play all the notes */ 00186 for (;;) { 00187 tone=pgm_read_byte(noteptr++); 00188 if (tone==0xff) break; 00189 for (i = pgm_read_byte(noteptr++);i > 0; i--) _delay_us(1000UL*TONE_LENGTH); 00190 tone = NONE;_delay_us(1000UL*TONE_GAP); 00191 } 00192 00193 /* Turn off interrupts and speaker */ 00194 TIMSK0 &= ~_BV(TOIE0); 00195 BEEP_PORT &= ~(1 << BEEP_BIT); 00196 ENTER_PUR &= ~(1 << PE7); 00197 } 00198 /** \} */