⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 audio_class.c

📁 最新版IAR FOR ARM(EWARM)5.11中的代码例子
💻 C
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************
 *
 *    Used with ICCARM and AARM.
 *
 *    (c) Copyright IAR Systems 2007
 *
 *    File name   : audio_class.c
 *    Description : AUDIO CLASS module
 *
 *    History :
 *    1. Date        : 18, October 2007
 *       Author      : Stanimir Bonev
 *       Description : Create
 *
 *    $Revision: 1.4 $
 **************************************************************************/
#include "audio_class.h"

volatile Boolean SempEna,MicEna;
Int32U  SempPeriod,DeltaPer,MicCurrBuffer;
volatile pInt16S pSpkData,pMicData;
volatile Int32U  SempPerCurrHold,Delta,MicSempCount,SempCount;
static union _Val
{
  Int32S Data;
  struct
  {
    Int16U DataLo;
    Int16S DataHi;
  };
} Val = {0x02000000};


const Int32U VolumeMul [] =
{
  // 256 - 0
  //-48dB- 0x0
  261,
  //-47dB- 0x1
  293,
  //-46dB- 0x2
  328,
  //-45dB- 0x3
  369,
  //-44dB- 0x4
  414,
  //-43dB- 0x5
  464,
  //-42dB- 0x6
  521,
  //-41dB- 0x7
  584,
  //-40dB- 0x8
  655,
  //-39dB- 0x9
  735,
  //-38dB- 0xA
  825,
  //-37dB- 0xB
  926,
  //-36dB- 0xC
  1039,
  //-35dB- 0xD
  1165,
  //-34dB- 0xE
  1308,
  //-33dB- 0xF
  1467,
  //-32dB- 0x10
  1646,
  //-31dB- 0x11
  1847,
  //-30dB- 0x12
  2072,
  //-29dB- 0x13
  2325,
  //-28dB- 0x14
  2609,
  //-27dB- 0x15
  2927,
  //-26dB- 0x16
  3285,
  //-25dB- 0x17
  3685,
  //-24dB- 0x18
  4135,
  //-23dB- 0x19
  4640,
  //-22dB- 0x1A
  5206,
  //-21dB- 0x1B
  5841,
  //-20dB- 0x1C
  6554,
  //-19dB- 0x1D
  7353,
  //-18dB- 0x1E
  8250,
  //-17dB- 0x1F
  9257,
  //-16dB- 0x20
  10387,
  //-15dB- 0x21
  11654,
  //-14dB- 0x22
  13076,
  //-13dB- 0x23
  14672,
  //-12dB- 0x24
  16462,
  //-11dB- 0x25
  18471,
  //-10dB- 0x26
  20724,
  //-9dB - 0x27
  23253,
  //-8dB - 0x28
  26090,
  //-7dB - 0x29
  29274,
  //-6dB - 0x2A
  32846,
  //-5dB - 0x2B
  36854,
  //-4dB - 0x2C
  41350,
  //-3dB - 0x2D
  46396,
  //-2dB - 0x2E
  52057,
  //-1dB - 0x2F
  58409,
  // 0dB - 0x30
  65536,
  // 1dB - 0x31
  73533,
  // 2dB - 0x32
  82505,
  // 3dB - 0x33
  92572,
  // 4dB - 0x34
  103868,
  // 5dB - 0x35
  116541,
  // 6dB - 0x36
  130762,
};

#pragma data_alignment=4
__no_init Int16S AudioSpkData[SampRerFrame * 3];

#pragma data_alignment=4
__no_init Int16S AudioMicData1[SampRerFrame * 2];
#pragma data_alignment=4
__no_init Int16S AudioMicData2[SampRerFrame * 2];

#pragma data_alignment=4
Int8U AudioBuf[2];

Int8U   AudioRequest,AudioCS,AudioCN,AudioId;
Int16U  AudioDataSize;

Int16S  AudioFeat1Vol;
Int32U  AudioSpkVolMul;
Boolean AudioFeat1Mute;

Int16S  AudioFeat2Vol;
Int32U  AudioMicVolMul;
Boolean AudioFeat2Mute;

/*************************************************************************
 * Function Name: UsbAudioClassInit
 * Parameters: none
 *
 * Return: none
 *
 * Description: USB Class Audio Init
 *
 *************************************************************************/
void UsbAudioClassInit (void)
{
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef   ADC_InitStructure;
RCC_ClocksTypeDef RCC_Clocks;
NVIC_InitTypeDef NVIC_InitStructure;
TIM1_TimeBaseInitTypeDef TIM1_TimeBaseInitStruct;
TIM1_OCInitTypeDef  TIM1_OCInitStructure;

  // Init Audio Class variables
  SempEna         =\
  AudioFeat1Mute  =\
  AudioFeat2Mute  = FALSE;
  SempCount       =\
  AudioFeat1Vol   =\
  AudioFeat2Vol   = 0;
  pSpkData        = AudioSpkData;
  SempPerCurrHold = SempPeriod;

  // Get different on chips' clocks.
  RCC_GetClocksFreq(&RCC_Clocks);

  // PWM DAC (TIM2) 10 bit PA8
  // Enable GPIO clock and release reset
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,
                         ENABLE);
  RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA,
                         DISABLE);

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  // Init PWM TIM1
  // Enable Timer1 clock and release reset
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
  RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM1,DISABLE);

  // Time base configuration
  TIM1_TimeBaseInitStruct.TIM1_Prescaler = 0;  // Max frequency
  TIM1_TimeBaseInitStruct.TIM1_CounterMode = TIM1_CounterMode_Up;
  TIM1_TimeBaseInitStruct.TIM1_Period = 0x3FF; // 10 bit resolution
  TIM1_TimeBaseInitStruct.TIM1_ClockDivision = 0;
  TIM1_TimeBaseInitStruct.TIM1_RepetitionCounter = 0;
  TIM1_TimeBaseInit(&TIM1_TimeBaseInitStruct);

  // Channel 1 Configuration in PWM mode
  TIM1_OCInitStructure.TIM1_OCMode = TIM1_OCMode_PWM1;
  TIM1_OCInitStructure.TIM1_OutputState = TIM1_OutputState_Enable;
  TIM1_OCInitStructure.TIM1_OutputNState = TIM1_OutputNState_Enable;
  TIM1_OCInitStructure.TIM1_Pulse = 0x200;
  TIM1_OCInitStructure.TIM1_OCPolarity = TIM1_OCPolarity_Low;
  TIM1_OCInitStructure.TIM1_OCNPolarity = TIM1_OCNPolarity_High;
  TIM1_OCInitStructure.TIM1_OCIdleState = TIM1_OCIdleState_Set;
  TIM1_OCInitStructure.TIM1_OCNIdleState = TIM1_OCIdleState_Reset;
  TIM1_OC1Init(&TIM1_OCInitStructure);
  // Double buffered
  TIM1_ARRPreloadConfig(ENABLE);
  // TIM1 counter enable
  TIM1_Cmd(ENABLE);

  // TIM1 Main Output Enable
  TIM1_CtrlPWMOutputs(ENABLE);

  // ADC init PA1
  // Enable ADC clock
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
  // ADC Deinit
  ADC_DeInit(ADC1);
  // Assign PA1 to ADC ch 1
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  GPIO_InitStructure.GPIO_Speed = (GPIOSpeed_TypeDef)0;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  // ADC Structure Initialization
  ADC_StructInit(&ADC_InitStructure);

  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfChannel = 1;
  ADC_Init(ADC1, &ADC_InitStructure);

  // Enable the ADC
  ADC_Cmd(ADC1, ENABLE);

  // ADC calibration
  // Enable ADC1 reset calibration register
  ADC_ResetCalibration(ADC1);
  // Check the end of ADC1 reset calibration register
  while(ADC_GetResetCalibrationStatus(ADC1) == SET);

  // Start ADC1 calibration
  ADC_StartCalibration(ADC1);
  // Check the end of ADC1 calibration
  while(ADC_GetCalibrationStatus(ADC1) == SET);

  // Configure channel
  ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_13Cycles5);

  // Init Sample Timer - Timer2
  // TIM2 clock enable
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
  // Reset TIM2
  TIM_DeInit(TIM2);
  // Time base configuration
  SempPeriod = RCC_Clocks.PCLK2_Frequency/SampFreq;
  DeltaPer = (SempPeriod/(SampRerFrame*2)) + 1;
  TIM_TimeBaseStructure.TIM_Period = SempPeriod;
  TIM_TimeBaseStructure.TIM_Prescaler = 0;      // max resolution
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

  // Disable double buffer of the APR register
  TIM_ARRPreloadConfig(TIM2, ENABLE);
  // Clear update interrupt bit
  TIM_ClearITPendingBit(TIM2,TIM_FLAG_Update);
  // Enable update interrupt
  TIM_ITConfig(TIM2,TIM_FLAG_Update,ENABLE);

  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQChannel;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = USB_INTR_AUDIO_SAMP_TIMER_PRIORITY; // max priority
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  // TIM2 enable counter
  TIM_Cmd(TIM2, ENABLE);

  UsbClassAudioConfigure(NULL);
  UsbCoreInit();

}

/*************************************************************************
 * Function Name: UsbClassAudioConfigure
 * Parameters:  pUsbDevCtrl_t pDev
 *
 * Return: none
 *
 * Description: USB Class Audio configure
 *
 *************************************************************************/
void UsbClassAudioConfigure (pUsbDevCtrl_t pDev)
{
  if(pDev == NULL)
  {
    if(UsbCoreReq(UsbCoreReqConfiquration) != 0)
    {
      SempEna = MicEna = FALSE;
    }
  }
  else
  {
    if((pDev->Configuration == 1))
    {
      if (pDev->AlternateSetting[USB_SPK_INTERFACE] == 1)
      {
        pSpkData = AudioSpkData;
        Delta = 0;
        USB_IO_Data(SpkEp,(pInt8U)pSpkData,SpkEpMaxSize,(void*)AudioInHadler);
      }
      if (pDev->AlternateSetting[USB_MIC_INTERFACE] == 1)
      {
        MicEna = FALSE;
        pMicData = AudioMicData1;
        MicCurrBuffer = 0;
        // Send microphone output buffer
        USB_IO_Data( MicEp,
                     NULL,
                     0,
                     NULL);
        USB_IO_Data( MicEp,
                     NULL,
                     0,
                     NULL);
        USB_IO_Data( MicEp,
                     NULL,
                     0,
                    (void*)AudioOutHadler);
      }
      else
      {
        MicEna = FALSE;
      }
    }
  }
}

/*************************************************************************
 * Function Name: AudioInHadler
 * Parameters:  USB_Endpoint_t EP
 *
 * Return: none
 *
 * Description: USB Class Audio Out EP handler
 *
 *************************************************************************/
static
void AudioInHadler (USB_Endpoint_t EP)
{
  assert(SpkEp == EP);

  if (EpCnfg[EP].Status == COMPLETE)
  {
    pSpkData += EpCnfg[EP].Size/sizeof(Int16U);
    if(pSpkData >= AudioSpkData + sizeof(AudioSpkData)/sizeof(Int16U))
    {
      pSpkData = AudioSpkData;
    }

    if(SempEna)
    {
      // Adapt sample rate
      if (Delta > (SampRerFrame * SubFrameSize))
      {
        SempPerCurrHold = SempPeriod - DeltaPer;
      }
      else if (Delta < (SampRerFrame * SubFrameSize))
      {
        SempPerCurrHold = SempPeriod + DeltaPer;
      }
      else
      {
        SempPerCurrHold = SempPeriod;
      }
    }
    else
    {
      if(pSpkData >= (AudioSpkData + (2*sizeof(AudioSpkData))/(3*sizeof(Int16U))))
      {
        // Enable output
        SempCount = 0;
        SempEna   = TRUE;
      }
    }
    ENTR_CRT_SECTION();
    Delta  += EpCnfg[EP].Size;
    EXT_CRT_SECTION();
  }
  else
  {
    // reset all
    pSpkData  = AudioSpkData;
    SempCount = 0;
    SempEna   = FALSE;
    SempPerCurrHold = SempPeriod;
    Delta = 0;
  }

  USB_IO_Data(SpkEp,(pInt8U)pSpkData,SpkEpMaxSize,(void*)AudioInHadler);
}

/*************************************************************************
 * Function Name: AudioOutHadler
 * Parameters:  USB_Endpoint_t EP
 *
 * Return: none
 *
 * Description: USB Class Audio In EP handler
 *
 *************************************************************************/
static
void AudioOutHadler (USB_Endpoint_t EP)
{
Int32U PacketLength;

  ENTR_CRT_SECTION();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -