Add polyphonic ringtones for received messages.

This commit is contained in:
dak664 2010-12-20 20:03:56 +00:00
parent 8af150ec0b
commit ac68ced90a
4 changed files with 115 additions and 8 deletions

View file

@ -32,22 +32,24 @@
*
* \brief
* This file implements a beep function to emit a beep sound from Raven's
* speaker.
* speaker. Also polyphonic ringtones.
*
* \author
* Mike Vidales mavida404@gmail.com
* David Kopf dak664@embarqmail.com
*
*/
#include "beep.h"
#include "key.h"
#include <stdlib.h>
#include "util/delay.h"
/**
* \addtogroup lcd
* \{
*/
/*---------------------------------------------------------------------------*/
/**
@ -90,4 +92,107 @@ beep(void)
ENTER_PUR &= ~(1 << PE7);
}
/*---------------------------------------------------------------------------*/
/**
* \brief Play polyphonic tune using buzzer. An 8 bit timer generates interrupts
* that flip the BEEP pin at the selected frequencies.
* On exit the beeper port pin is set low to shut down the speaker amplifier.
*/
/* Base interrupts per second, and interrupts for each note */
//#define BASE 31250
#define BASE 31250/2 //up one octave
#define NONE 0
#define C4 BASE/262
#define CS4 BASE/277
#define D4 BASE/294
#define DS4 BASE/311
#define E4 BASE/330
#define F4 BASE/349
#define FS4 BASE/370
#define G4 BASE/392
#define GS4 BASE/415
#define A4 BASE/440
#define AS4 BASE/466
#define B4 BASE/494
#define C5 BASE/523
#define CS5 BASE/554
#define D5 BASE/587
#define DS5 BASE/622
#define E5 BASE/659
#define F5 BASE/698
#define FS5 BASE/740
#define G5 BASE/784
#define GS5 BASE/831
#define A5 BASE/880
#define AS5 BASE/932
/* Tone reference length and internote gap, milliseconds */
#define TONE_LENGTH 60
#define TONE_GAP 20
static uint8_t tuneindex=0;
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};
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};
static uint8_t sandman1[] PROGMEM = {F4,2, G4,2, B4,4, A4,10, B4,2, B4,2, A4,2, B4,12, 0xff};
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};
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};
static volatile uint8_t icnt,tone;
#include <avr/interrupt.h>
ISR(TIMER0_OVF_vect)
{
if (tone == NONE) icnt = 0;
else if (icnt++ >= tone)
{
BEEP_PIN |= (1 << BEEP_BIT);
icnt = 0;
}
}
void play_ringtone(void)
{
uint8_t i,*noteptr;
/* What's next on the playlist? */
switch (tuneindex++) {
case 1 :beep();return;
case 2 :noteptr=sandman1;break;
case 3 :noteptr=furelise;break;
case 4 :noteptr=sandman2;break;
case 5 :noteptr=axel;break;
default:noteptr=pictures;tuneindex=1;break;
}
/* Turn on the power to the speaker. */
ENTER_DDR |= (1 << PE7);
ENTER_PUR |= (1 << PE7);
/* Setup port pin */
BEEP_DDR |= (1 << BEEP_BIT);
/* Start with no tone */
icnt = 0;
tone = NONE;
/* Clock 8 bit timer at maximum frequency (CS0=1), interrupt overflow */
/* 8MHz / 256 = 31250 interrupts per second */
TCCR0A |= _BV(CS00);
TCNT0 = 0;
TIMSK0 |= _BV(TOIE0);
/* Play all the notes */
for (;;) {
tone=pgm_read_byte(noteptr++);
if (tone==0xff) break;
for (i = pgm_read_byte(noteptr++);i > 0; i--) _delay_us(1000UL*TONE_LENGTH);
tone = NONE;_delay_us(1000UL*TONE_GAP);
}
/* Turn off interrupts and speaker */
TIMSK0 &= ~_BV(TOIE0);
BEEP_PORT &= ~(1 << BEEP_BIT);
ENTER_PUR &= ~(1 << PE7);
}
/** \} */

View file

@ -53,5 +53,6 @@
/** \} */
void beep(void);
void play_ringtone(void);
#endif /* BEEP_H */

View file

@ -268,13 +268,12 @@ read_menu(uint8_t ndx)
}
/*---------------------------------------------------------------------------*/
char top_menu_text[20];
/**
* \brief This will toggle the CONTIKI and 6LOWPAN LCD menus in the main
* menu position, unless alternate text has been sent from the 1284p.
* The other menus will display normally.
*/
char top_menu_text[20];
void
check_main_menu(void)
{
@ -307,8 +306,8 @@ uint8_t showtop=0;
void
check_menu(void)
{
if(menu.text == menu_text4){
menu_clear_temp();
if(menu.text == menu_text12){
menu_clear_temp();
}
if(menu.text == menu_text10){

View file

@ -435,10 +435,12 @@ uart_serial_rcv_frame(uint8_t wait_for_ack)
lcd_symbol_clr(LCD_SYMBOL_BELL);
break;
case REPORT_TEXT_MSG:
/* Copy text message to menu buffer and fall through to beep */
/* Copy text message to menu buffer and play ringtone */
/* Prezero in case no string terminator in command */
for (i=0;i<sizeof(top_menu_text);i++) top_menu_text[i]=0;
memcpy(&top_menu_text,(char *)payload,sizeof(top_menu_text)-1); //leave zero byte at end
memcpy(&top_menu_text,(char *)payload,sizeof(top_menu_text)-1); //leave zero byte at end
play_ringtone();
break;
case REPORT_PING_BEEP:
lcd_symbol_set(LCD_SYMBOL_BELL);
beep();