/******************************************************************************
�� �� ����Buzzer.c
�����������������������ļ�
��    �ߣ�����
��    ����V2.0
��    �ڣ�2018.4.7
******************************************************************************/

#include "Buzzer.h"

BuzzerPlayCtrlStruct  BuzzerPlayCtrl;

/******************************************************************************
��������Buzzer_Start_Up
��  �ܣ���������ʼ��������
        ������PWMʹ��CLKSA/CLKSBʱ��Դ,�Ƽ���ʱ��ԴƵ��Ϊ50kHz~100kHz
��  ������
����ֵ����
******************************************************************************/
void Buzzer_Start_Up(void)
{
  BuzzerPlayCtrl.Mode  = BUZZER_MODE_IDLE;
  
  BuzzerPlayCtrl.Track = 0;
  BuzzerPlayCtrl.Note  = 0;
  BuzzerPlayCtrl.Timer = 0;
  BuzzerPlayCtrl.Fade  = 0;
  
  BUZZER_CTRL = 0;
  PWM_Channel_Stop(BUZZER_PWM_CHANNEL);
  PWM_Channel_Init(BUZZER_PWM_CHANNEL, PWM_CLOCK_SA, PWM_POL_POS, PWM_LEFT_ALIGN, PWM4_PP4);
}

/******************************************************************************
��������Buzzer_Shutdown
��  �ܣ��رշ�����
��  ������
����ֵ����
******************************************************************************/
void Buzzer_Shutdown(void)
{
  BuzzerPlayCtrl.Mode  = BUZZER_MODE_IDLE;
  
  BuzzerPlayCtrl.Track = 0;
  BuzzerPlayCtrl.Note  = 0;
  BuzzerPlayCtrl.Timer = 0;
  BuzzerPlayCtrl.Fade  = 0;
  
  BUZZER_CTRL = 0;
  PWM_Channel_Stop(BUZZER_PWM_CHANNEL);
}

/******************************************************************************
��������Buzzer_Play_Track
��  �ܣ����β���ָ������
��  ����TrackID - ������
����ֵ����
******************************************************************************/
void Buzzer_Play_Track(uint8_t TrackID)
{
  if (BuzzerPlayCtrl.Mode)
    return;
  
  if (TrackID >= SND_TRACK_TOTAL_NUM)
    return;
  
  BUZZER_CTRL = 1;
  
  BuzzerPlayCtrl.Track = TrackID;
  BuzzerPlayCtrl.Note  = 0;
  BuzzerPlayCtrl.Timer = (uint16_t)SndTracks[TrackID].PreCharge * 20;
  BuzzerPlayCtrl.Fade  = 0;
  
  BuzzerPlayCtrl.Mode  = BUZZER_MODE_SINGLE;
}

/******************************************************************************
��������Buzzer_Play_Track
��  �ܣ�ѭ������ָ������
��  ����TrackID - ������
����ֵ����
******************************************************************************/
void Buzzer_Repeat_Play_Track(uint8_t TrackID)
{
  if (BuzzerPlayCtrl.Mode)
    return;
  
  if (TrackID >= SND_TRACK_TOTAL_NUM)
    return;
  
  BUZZER_CTRL = 1;
  
  BuzzerPlayCtrl.Track = TrackID;
  BuzzerPlayCtrl.Note  = 0;
  BuzzerPlayCtrl.Timer = (uint16_t)SndTracks[TrackID].PreCharge * 20;
  BuzzerPlayCtrl.Fade  = 0;
  
  BuzzerPlayCtrl.Mode  = BUZZER_MODE_LOOP;
}

/******************************************************************************
��������Buzzer_Stop_Play
��  �ܣ�ֹͣ��������
��  ������
����ֵ����
******************************************************************************/
void Buzzer_Stop_Play(void)
{
  BuzzerPlayCtrl.Mode  = BUZZER_MODE_IDLE;
  
  BuzzerPlayCtrl.Track = 0;
  BuzzerPlayCtrl.Note  = 0;
  BuzzerPlayCtrl.Timer = 0;
  BuzzerPlayCtrl.Fade  = 0;
  
  BUZZER_CTRL = 0;
  PWM_Channel_Stop(BUZZER_PWM_CHANNEL);
}

/******************************************************************************
��������Buzzer_Play_ISR
��  �ܣ������������жϷ�����
��  ������
����ֵ����
******************************************************************************
ע  �⣺�÷���������Ƕ�뵽50us��ʱ�ж���
******************************************************************************/
void Buzzer_Play_ISR(void)
{
  if (BuzzerPlayCtrl.Mode)
  {
    if (BuzzerPlayCtrl.Timer)
      BuzzerPlayCtrl.Timer--;
    
    if (BuzzerPlayCtrl.Timer == 0)
    {
      if (BuzzerPlayCtrl.Note < SndTracks[BuzzerPlayCtrl.Track].NoteNum)
      {
        BUZZER_CTRL = 1;
        
        if (SndTracks[BuzzerPlayCtrl.Track].Note[BuzzerPlayCtrl.Note].Freq)
        {
          PWM_Channel_Set_Freq(BUZZER_PWM_CHANNEL, SndTracks[BuzzerPlayCtrl.Track].Note[BuzzerPlayCtrl.Note].Freq);
          PWM_Channel_Set_Duty_Cycle(BUZZER_PWM_CHANNEL, SndTracks[BuzzerPlayCtrl.Track].Note[BuzzerPlayCtrl.Note].Duty);
          PWM_Channel_Start(BUZZER_PWM_CHANNEL);
        }
        else
          PWM_Channel_Stop(BUZZER_PWM_CHANNEL);
        
        BuzzerPlayCtrl.Timer = SndTracks[BuzzerPlayCtrl.Track].Note[BuzzerPlayCtrl.Note].Interval * 20;
        BuzzerPlayCtrl.Fade  = SndTracks[BuzzerPlayCtrl.Track].Note[BuzzerPlayCtrl.Note].Fade * 20;
        BuzzerPlayCtrl.Note++;
      }
      else
      {
        if (BuzzerPlayCtrl.Mode == BUZZER_MODE_LOOP)
          BuzzerPlayCtrl.Note  = 0;
        else
        {
          BUZZER_CTRL = 0;
          PWM_Channel_Stop(BUZZER_PWM_CHANNEL);
          BuzzerPlayCtrl.Mode  = BUZZER_MODE_IDLE;
        }        
      }
    }
    else if (BuzzerPlayCtrl.Timer < BuzzerPlayCtrl.Fade)
      BUZZER_CTRL = 0;
  }
}