Contiki 2.6

beep.c

Go to the documentation of this file.
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 /** \}   */