diff --git a/platform/avr-ravenlcd/beep.c b/platform/avr-ravenlcd/beep.c index 775f49671..34f2ee23f 100644 --- a/platform/avr-ravenlcd/beep.c +++ b/platform/avr-ravenlcd/beep.c @@ -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 +#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 +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); +} /** \} */ diff --git a/platform/avr-ravenlcd/beep.h b/platform/avr-ravenlcd/beep.h index cc6a1cd06..71d284d57 100644 --- a/platform/avr-ravenlcd/beep.h +++ b/platform/avr-ravenlcd/beep.h @@ -53,5 +53,6 @@ /** \} */ void beep(void); +void play_ringtone(void); #endif /* BEEP_H */ diff --git a/platform/avr-ravenlcd/raven3290.c b/platform/avr-ravenlcd/raven3290.c index 5d7b400c1..d63ebeda9 100644 --- a/platform/avr-ravenlcd/raven3290.c +++ b/platform/avr-ravenlcd/raven3290.c @@ -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){ diff --git a/platform/avr-ravenlcd/uart.c b/platform/avr-ravenlcd/uart.c index 32e2a7538..116083276 100644 --- a/platform/avr-ravenlcd/uart.c +++ b/platform/avr-ravenlcd/uart.c @@ -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