/******************************************************************************

   buzzer.c - Routines to intialze and sound the optional User Buzzer 
              using a PWM for the Lincoln 60

                      by Micromint Support <support@micromint.com>    June-2011

  Copyright (c) 2008-2011 Micromint USA LLC  All rights reserved.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions
  are met:

  1. Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in
     the documentation and/or other materials provided with the
     distribution.
  3. Neither the name Micromint nor the names of its contributors may
     be used to endorse or promote products derived from this software
     without specific prior written permission.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  POSSIBILITY OF SUCH DAMAGE.

*******************************************************************************/
#include "buzzer.h"

/******************************************************************************

 Start sounding the buzzer using PWM

*******************************************************************************/
void Sound_Buzzer_PWM(uint32_t uint32_tFrequency)
{
  uint32_t uint32_tMatch0;
  PWM_MATCHCFG_Type PWMMatchCfgDat;
  PINSEL_CFG_Type PinCfg;
  PWM_TIMERCFG_Type PWMCfgDat;
  /* Configure the pin for the buzzer */
  PinCfg.Funcnum = BUZZER_FUNC_PWM;  
  PinCfg.OpenDrain = BUZZER_OPENDRAIN;
  PinCfg.Pinmode = BUZZER_PINMODE;
  PinCfg.Portnum = BUZZER_PORT;
  PinCfg.Pinnum = BUZZER_PIN;
  PINSEL_ConfigPin(&PinCfg);
  /* Make sure PWM is disabled */
  PWM_Cmd(BUZZER_PWM, DISABLE);
   /* Initialize PWM peripheral */
  PWMCfgDat.PrescaleOption = PWM_TIMER_PRESCALE_TICKVAL;
  PWMCfgDat.PrescaleValue = 1;
  PWM_Init(BUZZER_PWM, PWM_MODE_TIMER, (void *) &PWMCfgDat);
  /* Set the PWM frequency */
  uint32_tMatch0 = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_PWM1)/uint32_tFrequency;
  /* Load the frequency into Match Channel 0 */
  PWM_MatchUpdate(BUZZER_PWM, 0,  uint32_tMatch0, PWM_MATCH_UPDATE_NOW);
  /* PWM Timer/Counter will be reset when channel 0 matching, no interrupt when
     match, and no stop when match */
  PWMMatchCfgDat.IntOnMatch = DISABLE;
  PWMMatchCfgDat.MatchChannel = 0;
  PWMMatchCfgDat.ResetOnMatch = ENABLE;
  PWMMatchCfgDat.StopOnMatch = DISABLE;
  PWM_ConfigMatch(BUZZER_PWM, &PWMMatchCfgDat);
  /* Setup PWM channel used the green LED */
  PWMMatchCfgDat.IntOnMatch = DISABLE;
  PWMMatchCfgDat.ResetOnMatch = DISABLE;
  PWMMatchCfgDat.StopOnMatch = DISABLE;
  /* Set up match value for green LED a 50% duty cycle*/
  PWM_MatchUpdate(BUZZER_PWM, BUZZER_CHANNEL, uint32_tMatch0/2, PWM_MATCH_UPDATE_NOW);
  PWMMatchCfgDat.MatchChannel = BUZZER_MATCH;
  PWM_ConfigMatch(BUZZER_PWM, &PWMMatchCfgDat);
  PWM_ChannelCmd(BUZZER_PWM, BUZZER_CHANNEL, ENABLE);
  PWM_ResetCounter(BUZZER_PWM);
  PWM_CounterCmd(BUZZER_PWM, ENABLE);
  /* Start PWM now */
  PWM_Cmd(BUZZER_PWM, ENABLE);
}

/******************************************************************************

 Stop sounding the buzzer using PWM

*******************************************************************************/
void Stop_Buzzer_PWM(void)
{
  PWM_ChannelCmd(BUZZER_PWM, BUZZER_CHANNEL, DISABLE);
}
	
/******************************************************************************

 Start sounding the buzzer using a timer and match output

*******************************************************************************/
void Sound_Buzzer_Timer(uint32_t uint32_tFrequency)
{
  PINSEL_CFG_Type PinCfg;
  TIM_TIMERCFG_Type TIM_ConfigStruct;
  TIM_MATCHCFG_Type TIM_MatchConfigStruct ;

  /* Configure the pin for the buzzer */
  PinCfg.Funcnum = BUZZER_FUNC_MATCH;
  PinCfg.OpenDrain = BUZZER_OPENDRAIN;
  PinCfg.Pinmode = BUZZER_PINMODE;
  PinCfg.Portnum = BUZZER_PORT;
  PinCfg.Pinnum = BUZZER_PIN;
  PINSEL_ConfigPin(&PinCfg);

  /* Initialize timer prescale count time to 1uS */
  TIM_ConfigStruct.PrescaleOption = TIM_PRESCALE_USVAL;
  TIM_ConfigStruct.PrescaleValue = 1;
  /* use channel 0, MR0 */
  TIM_MatchConfigStruct.MatchChannel = BUZZER_MATCH_CHANNEL;
  /* Enable interrupt when MR0 matches the value in TC register */
  TIM_MatchConfigStruct.IntOnMatch   = FALSE;
  /* Enable reset on MR0: TIMER will reset if MR0 matches it */
  TIM_MatchConfigStruct.ResetOnMatch = TRUE;
  /* Stop on MR0 if MR0 matches it */
  TIM_MatchConfigStruct.StopOnMatch  = FALSE;
  /* Toggle MR0.0 pin if MR0 matches it */
  TIM_MatchConfigStruct.ExtMatchOutputType =TIM_EXTMATCH_TOGGLE;
  /* Set Match value based on the desired frequency */
  TIM_MatchConfigStruct.MatchValue = 500000/uint32_tFrequency;
  /* Make sure Timer is disabled before changing configuration */
  TIM_Cmd(BUZZER_TIMER,DISABLE);
  /* Set configuration for Tim_config and Tim_MatchConfig */
  TIM_Init(BUZZER_TIMER, TIM_TIMER_MODE,&TIM_ConfigStruct);
  TIM_ConfigMatch(BUZZER_TIMER,&TIM_MatchConfigStruct);
  /* To start timer 0 */
  TIM_Cmd(BUZZER_TIMER,ENABLE);
}
/******************************************************************************

 Stop sounding the buzzer using a timer and match output

*******************************************************************************/
void Stop_Buzzer_Timer(void)
{
  // Stop the timer
  TIM_Cmd(BUZZER_TIMER,DISABLE);
}