3#include <avr/interrupt.h> 
    6#ifdef __AVR_ATmega32U4__ 
   10#define BUZZER      (1 << PORTD7) 
   12#define TIMER4_CLK_8  0x4  
   14#define ENABLE_TIMER_INTERRUPT()   TIMSK4 = (1 << TOIE4) 
   15#define DISABLE_TIMER_INTERRUPT()  TIMSK4 = 0 
   20#define BUZZER_DDR  DDRD 
   21#define BUZZER      (1 << PORTD3) 
   23#define TIMER2_CLK_32  0x3   
   25static const unsigned int cs2_divider[] = {0, 1, 8, 32, 64, 128, 256, 1024};
 
   27#define ENABLE_TIMER_INTERRUPT()   TIMSK2 = (1 << TOIE2) 
   28#define DISABLE_TIMER_INTERRUPT()  TIMSK2 = 0 
   32unsigned char buzzerInitialized = 0;
 
   33volatile unsigned char buzzerFinished = 1;  
 
   34const char * 
volatile buzzerSequence = 0;
 
   38static volatile unsigned int buzzerTimeout = 0;    
 
   41extern volatile unsigned char buzzerFinished;  
 
   42extern const char * 
volatile buzzerSequence;
 
   45static volatile unsigned char use_program_space; 
 
   49static volatile unsigned char octave = 4;                 
 
   50static volatile unsigned int whole_note_duration = 2000;  
 
   51static volatile unsigned int note_type = 4;               
 
   52static volatile unsigned int duration = 500;              
 
   53static volatile unsigned int volume = 15;                 
 
   54static volatile unsigned char staccato = 0;               
 
   57static volatile unsigned char staccato_rest_duration;  
 
   60static void nextNote();
 
   62#ifdef __AVR_ATmega32U4__ 
   67  if (buzzerTimeout-- == 0)
 
   69    DISABLE_TIMER_INTERRUPT();
 
   71    TCCR4B = (TCCR4B & 0xF0) | TIMER4_CLK_8;  
 
   72    unsigned int top = (F_CPU/16) / 1000;     
 
   88  if (buzzerTimeout-- == 0)
 
   90    DISABLE_TIMER_INTERRUPT();
 
   92    TCCR2B = (TCCR2B & 0xF8) | TIMER2_CLK_32; 
 
   93    OCR2A = (F_CPU/64) / 1000;                
 
  104inline void PololuBuzzer::init()
 
  106  if (!buzzerInitialized)
 
  108    buzzerInitialized = 1;
 
  114void PololuBuzzer::init2()
 
  116  DISABLE_TIMER_INTERRUPT();
 
  118#ifdef __AVR_ATmega32U4__ 
  153  unsigned int top = (F_CPU/16) / 1000; 
 
  182  OCR2A = (F_CPU/64) / 1000;  
 
  186  BUZZER_DDR |= BUZZER;    
 
  200                     unsigned char volume)
 
  205  unsigned int timeout;
 
  206  unsigned char multiplier = 1;
 
  214  unsigned char min = 40 * multiplier;
 
  217  if (multiplier == 1 && freq > 10000)
 
  220#ifdef __AVR_ATmega32U4__ 
  222  unsigned char dividerExponent = 0;
 
  225  top = (
unsigned int)(((F_CPU/2 * multiplier) + (freq >> 1))/ freq);
 
  230    top = (
unsigned int)((((F_CPU/2 >> (dividerExponent)) * multiplier) + (freq >> 1))/ freq);
 
  234  unsigned char newCS2 = 2; 
 
  235  unsigned int divider = cs2_divider[newCS2];
 
  238  top = (
unsigned int)(((F_CPU/16 * multiplier) + (freq >> 1))/ freq);
 
  242    divider = cs2_divider[++newCS2];
 
  243    top = (
unsigned int)(((F_CPU/2/divider * multiplier) + (freq >> 1))/ freq);
 
  248  if (multiplier == 10)
 
  249    freq = (freq + 5) / 10;
 
  254    timeout = (
unsigned int)((
long)dur * freq / 1000);
 
  259  DISABLE_TIMER_INTERRUPT();      
 
  261#ifdef __AVR_ATmega32U4__ 
  262  TCCR4B = (TCCR4B & 0xF0) | (dividerExponent + 1); 
 
  265  unsigned int width = top >> (16 - volume);        
 
  268  buzzerTimeout = timeout;                          
 
  272  TCCR2B = (TCCR2B & 0xF8) | newCS2;  
 
  274  OCR2B = top >> (16 - volume);       
 
  275  buzzerTimeout = timeout;            
 
  280  ENABLE_TIMER_INTERRUPT();
 
  295                 unsigned char volume)
 
  322  unsigned int freq = 0;
 
  323  unsigned char offset_note = note - 16;
 
  334  else if (offset_note > 95)
 
  337  unsigned char exponent = offset_note / 12;
 
  341  switch (offset_note - exponent * 12)  
 
  383    freq = freq << exponent;  
 
  385      freq = (freq + 5) / 10;  
 
  390    freq = (freq * 64 + 2) / 5;  
 
  402  return !buzzerFinished || buzzerSequence != 0;
 
  465  DISABLE_TIMER_INTERRUPT();  
 
  466  buzzerSequence = notes;
 
  467  use_program_space = 0;
 
  468  staccato_rest_duration = 0;
 
  474  DISABLE_TIMER_INTERRUPT();  
 
  475  buzzerSequence = notes_p;
 
  476  use_program_space = 1;
 
  477  staccato_rest_duration = 0;
 
  485  DISABLE_TIMER_INTERRUPT();          
 
  487#ifdef __AVR_ATmega32U4__ 
  488  TCCR4B = (TCCR4B & 0xF0) | TIMER4_CLK_8;  
 
  489  unsigned int top = (F_CPU/16) / 1000;     
 
  495  TCCR2B = (TCCR2B & 0xF8) | TIMER2_CLK_32; 
 
  496  OCR2A = (F_CPU/64) / 1000;                
 
  506static char currentCharacter()
 
  511    if(use_program_space)
 
  512      c = pgm_read_byte(buzzerSequence);
 
  516    if(c >= 
'A' && c <= 
'Z')
 
  518  } 
while(c == 
' ' && (buzzerSequence ++));
 
  526static unsigned int getNumber()
 
  528  unsigned int arg = 0;
 
  531  char c = currentCharacter();
 
  532  while(c >= 
'0' && c <= 
'9')
 
  537    c = currentCharacter();
 
  543static void nextNote()
 
  545  unsigned char note = 0;
 
  546  unsigned char rest = 0;
 
  547  unsigned char tmp_octave = octave; 
 
  548  unsigned int tmp_duration; 
 
  549  unsigned int dot_add;
 
  554  if(staccato && staccato_rest_duration)
 
  557    staccato_rest_duration = 0;
 
  564  c = currentCharacter();
 
  573    goto parse_character;
 
  577    goto parse_character;
 
  601    note_type = getNumber();
 
  602    duration = whole_note_duration/note_type;
 
  603    goto parse_character;
 
  606    if(currentCharacter() == 
'l')
 
  611      staccato_rest_duration = 0;
 
  614    goto parse_character;
 
  617    octave = tmp_octave = getNumber();
 
  618    goto parse_character;
 
  625    whole_note_duration = 60*400/getNumber()*10;
 
  626    duration = whole_note_duration/note_type;
 
  627    goto parse_character;
 
  630    volume = getNumber();
 
  631    goto parse_character;
 
  635    whole_note_duration = 2000;
 
  642    tmp_duration = duration;
 
  643    goto parse_character;
 
  649  note += tmp_octave*12;
 
  652  c = currentCharacter();
 
  653  while(c == 
'+' || c == 
'#')
 
  657    c = currentCharacter();
 
  663    c = currentCharacter();
 
  667  tmp_duration = duration;
 
  670  if(c > 
'0' && c < 
'9')
 
  671    tmp_duration = whole_note_duration/getNumber();
 
  675  dot_add = tmp_duration/2;
 
  676  while(currentCharacter() == 
'.')
 
  679    tmp_duration += dot_add;
 
  685    staccato_rest_duration = tmp_duration / 2;
 
  686    tmp_duration -= staccato_rest_duration;
 
  710  play_mode_setting = mode;
 
  727  if(buzzerFinished && buzzerSequence != 0)
 
  729  return buzzerSequence != 0;
 
#define DIV_BY_10
frequency bit that indicates Hz/10  e.g. frequency = (445 | DIV_BY_10) gives a frequency of 44....
#define PLAY_AUTOMATIC
Specifies that the sequence of notes will play with no further action required by the user.
#define SILENT_NOTE
silences buzzer for the note duration
static void playFromProgramSpace(const char *sequence)
Plays the specified sequence of notes from program space.
static void play(const char *sequence)
Plays the specified sequence of notes.
static void stopPlaying()
Stops any note, frequency, or melody being played.
static unsigned char playCheck()
Starts the next note in a sequence, if necessary, in PLAY_CHECK mode.
static unsigned char isPlaying()
Checks whether a note, frequency, or sequence is being played.
static void playFrequency(unsigned int freq, unsigned int duration, unsigned char volume)
Plays the specified frequency for the specified duration.
static void playNote(unsigned char note, unsigned int duration, unsigned char volume)
Plays the specified note for the specified duration.
static void playMode(unsigned char mode)
Controls whether play() sequence is played automatically or must be driven with playCheck().