/**
  ******************************************************************************
  * @file buzzer.c
  * @brief This file contains all the functions for the BUZZER.
  * @author STMicroelectronics - MCD Application Team
  * @version V1.1.0
  * @date    09/14/2009
  ******************************************************************************
  *
  */

// Includes ------------------------------------------------------------------
#include "buzzer.h"

// Private typedef -----------------------------------------------------------

// ----------------------------------------------
// All values are for Timer clock equal to 4MHz 
/* ARR = freq_timer / freq_note
/*----------------------------------------------*/

// Octave 3 
__CONST Note_TypeDef NOTES3[] =
    {
        {
            NOTE_DO, 15289
        }
        , /* 262Hz */
        {NOTE_DOd, 14431}, /* 277Hz */
        {NOTE_RE, 13621}, /* 294Hz */
        {NOTE_REd, 12856}, /* 311Hz */
        {NOTE_MI, 12135}, /* 330Hz */
        {NOTE_FA, 11454}, /* 349Hz */
        {NOTE_FAd, 10811}, /* 370Hz */
        {NOTE_SOL, 10204}, /* 392Hz */
        {NOTE_SOLd, 9631}, /* 415Hz */
        {NOTE_LA, 9091}, /* 440Hz */
        {NOTE_LAd, 8581}, /* 466Hz */
        {NOTE_SI, 8099}, /* 494Hz */
        {NOTE_SILENCE, 0},
        {0, 0, 0} /* end of list */
    };

// Octave 4 
__CONST Note_TypeDef NOTES4[] =
    {
        {
            NOTE_DO, 7645
        }
        , /* 523Hz */
        {NOTE_DOd, 7215}, /* 554Hz */
        {NOTE_RE, 6810}, /* 587Hz */
        {NOTE_REd, 6428}, /* 622Hz */
        {NOTE_MI, 6067}, /* 659Hz */
        {NOTE_FA, 5727}, /* 699Hz */
        {NOTE_FAd, 5405}, /* 740Hz */
        {NOTE_SOL, 5102}, /* 784Hz */
        {NOTE_SOLd, 4816}, /* 831Hz */
        {NOTE_LA, 4545}, /* 880Hz */
        {NOTE_LAd, 4290}, /* 932Hz */
        {NOTE_SI, 4050}, /* 988Hz */
        {NOTE_SILENCE, 0},
        {0, 0, 0} /* end of list */
    };

// Octave 5 
__CONST Note_TypeDef NOTES5[] =
    {
        {
            NOTE_DO, 3822
        }
        , /* 1047Hz */
        {NOTE_DOd, 3608}, /* 1109Hz */
        {NOTE_RE, 3405}, /* 1175Hz */
        {NOTE_REd, 3214}, /* 1245Hz */
        {NOTE_MI, 3034}, /* 1319Hz */
        {NOTE_FA, 2863}, /* 1397Hz */
        {NOTE_FAd, 2703}, /* 1480Hz */
        {NOTE_SOL, 2551}, /* 1568Hz */
        {NOTE_SOLd, 2408}, /* 1661Hz */
        {NOTE_LA, 2273}, /* 1760Hz */
        {NOTE_LAd, 2145}, /* 1865Hz */
        {NOTE_SI, 2025}, /* 1976Hz */
        {NOTE_SILENCE, 0},
        {0, 0, 0} /* end of list */
    };

/* Syntax
 3 = set octave 3
 4 = set octave 4
 , = set eighth note
 . = set quarter note (',' + ',')
 ; = set 3 eighth note ('.' + ',')
 : = set half note ('.' + '.')
 % = set whole note (':' + ':')
 */
__CONST Melody_TypeDef MELODIES[] =
    {
    {"Bon Tabac",     "4.cdec:d.de:ffee.cdec:d.de:fgc"},
    {"Clair Lune",    "4.cccd:ed.cedd:c"},
		{"Magnum",        "4;ef.g ;a,g .agagag ;a,g.ag 5:c 4:b ;a,g .agagag ;a,g .ag;ef.g ;a,g .agagag 5:c 4:b ;a,g .agagag 3;b 4c.d;ef.g %a"},
		{"Pulp Fiction",  "3:e.ef:Gab.b4c:Dc3%bse.ef:Gab.b4c:Dc3%b"},
		{"Indiana Jones", "3.d,sDfs%A.sc,sd%D.s.f,sgas4:D3.sg,sa.A,As4.c,c3s4:d3.d,sDfs%A"},
    {0, 0} /* end of list */
    };

// Private define ------------------------------------------------------------
// Private macro -------------------------------------------------------------
// Private variables ---------------------------------------------------------
// Private function prototypes -----------------------------------------------
// Private functions ---------------------------------------------------------

  // * @addtogroup Buzzer_Functions


void PlayTunePWM(uint16_t freq, uint16_t duration)
{

    uint16_t dutycycle;

    if (freq != 0)
    {
        // Set frequency 
        TIM3->ARRH = (uint8_t)(freq >> 8);
        TIM3->ARRL = (uint8_t)(freq);
        // Set duty cycle = freq/2 = 50% 
        dutycycle = (uint16_t)(freq >> 1);
        TIM3->CCR2H = (uint8_t)(dutycycle >> 8);
        TIM3->CCR2L = (uint8_t)(dutycycle);
        // Enable OC2 
        TIM3->CCER1 |= TIM_CCER1_CC2E;
    }

    WaitDelay(duration);

    // Disable OC4 
    TIM3->CCER1 &= (uint8_t)(~TIM_CCER1_CC2E);

}

void PlayNote(uint8_t note, uint8_t octave, uint16_t duration)
{

    Note_TypeDef *pNote;

    // Select the octave table 
    switch (octave)
    {
    case 3:
        pNote = NOTES3;
        break;
    case 5:
        pNote = NOTES5;
        break;
    default:
        pNote = NOTES4;
        break;
    }

    // Search note in table 
    while (pNote->Letter)
    {
        // Note is found, play it 
        if (pNote->Letter == note)
        {
            PlayTunePWM(pNote->Freq, duration);
            // Add a silence after the note 
            WaitDelay(DURATION_1);
            return;
        }
        pNote++;
    }

}

void PlayMelody(uint8_t *notes)
{

    JOYSTICK_ID_T Key;
    uint8_t octave = 4;
    uint16_t duration = DURATION_2;

    while (*notes != '\0')
    {
			if ((*notes =='3')||(*notes == '4')||(*notes=='5'))
		  {   
			    octave = 4;
          notes++;
		  }
			else if (*notes ==',')
		  {
			     duration = DURATION_1;
           *notes++;
			}
			else if (*notes == '.')
		  {
            duration = DURATION_2;
            *notes++;
			}		
			else if (*notes == ';')
		  {
            duration = (uint16_t)(DURATION_1 + DURATION_2);
            *notes++;
			}		
			else if (*notes == ':')
		  {
            duration = DURATION_3;
            *notes++;
			}	
			else if (*notes == '%')
		  {
            duration = DURATION_4;
            *notes++;
			}	
			else if (*notes == ' ')
		  {
            *notes++;
			}	
      else
			{
			      PlayNote(*notes, octave, duration);
            *notes++;
      }

        // Allow to stop melody 
        Key = ReadJoystick();
        if ((Key != J_NONE) && (Key != J_RELEASED))
        {
            break;
        }

        // Allow to do something else while melody is playing 
#ifdef ENABLE_MELODY_CALLBACK
        MelodyCallBack();
#endif

    }
}


