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

📄 usbaudio.c

📁 NXP产品LPC23XX的开发板的源文件
💻 C
字号:
/*----------------------------------------------------------------------------
 *      Name:    DEMO.C
 *      Purpose: USB Audio Demo
 *      Version: V1.10
 *----------------------------------------------------------------------------
 *      This software is supplied "AS IS" without any warranties, express,
 *      implied or statutory, including but not limited to the implied
 *      warranties of fitness for purpose, satisfactory quality and
 *      noninfringement. Keil extends you a royalty-free right to reproduce
 *      and distribute executable files created using this software for use
 *      on Philips LPC2xxx microcontroller devices only. Nothing else gives
 *      you the right to use this software.
 *
 *      Copyright (c) 2005-2006 Keil Software.
 *---------------------------------------------------------------------------*/

#include <LPC230X.H>                        /* LPC230x definitions */

#include "type.h"

#include "usb.h"
#include "usbcfg.h"
#include "usbhw.h"
#include "usbcore.h"
#include "target.h"
#include "irq.h"
#include "usbaudio.h"

#define ADC_POLLING		0

BYTE  Mute;                                 /* Mute State */
DWORD Volume;                               /* Volume Level */
BYTE  AudioON = 1;			/* Controlled by WEB server */

#if USB_DMA
  #if KEIL_IDE
  DWORD InfoBuf[P_C] __at  DMA_BUF_ADR;       /* Packet Info Buffer */
  short DataBuf[B_S] __at (DMA_BUF_ADR+4*P_C);/* Data Buffer */
  #else
  DWORD *InfoBuf = (DWORD *)(DMA_BUF_ADR);
  short *DataBuf = (short *)(DMA_BUF_ADR + 4*P_C);
  #endif
#else
short DataBuf[B_S];                         /* Data Buffer */
#endif

WORD  DataOut;                              /* Data Out Index */
WORD  DataIn;                               /* Data In Index */

BYTE  DataRun;                              /* Data Stream Run State */

WORD  PotVal;                               /* Potenciometer Value */

DWORD VUM;                                  /* VU Meter */

DWORD Tick;                                 /* Time Tick */

/*
 * Timer Counter 0 Interrupt Service Routine
 *   executed each 31.25us (32kHz frequency)
 */

volatile DWORD ADC0Value;
volatile DWORD ADC0IntDone = 0;
/******************************************************************************
** Function name:		ADC0Handler
**
** Descriptions:		ADC0 interrupt handler
**
** parameters:			None
** Returned value:		None
** 
******************************************************************************/
void ADC0Handler (void) __irq 
{
    DWORD regVal;
  
    IENABLE;			/* handles nested interrupt */

    regVal = AD0STAT;		/* Read ADC will clear the interrupt */
    if ( regVal & (1 << 16) )
    {
		switch ( regVal & 0xFF )	/* check DONE bit */
		{
	      case 0x01:
			ADC0Value = AD0DR0;
			ADC0IntDone = 1;
		  break;
	      default:
		  break;
		}
		AD0CR &= 0xF8FFFFFF;	/* stop ADC now */
    }

    IDISABLE;
    VICVectAddr = 0;		/* Acknowledge Interrupt */
}

/*
 * Get Potenciometer Value
 */

void get_potval (void) {
#if ADC_POLLING
  DWORD val;
  AD0CR |= 0x01000000;                      /* Start A/D Conversion */
  do {
    val  = AD0GDR;                          /* Read A/D Data Register */
  } while ((val & 0x80000000) == 0);        /* Wait for end of A/D Conversion */
  AD0CR &= ~0x01000000;                     /* Stop A/D Conversion */
  PotVal = ((val >> 8) & 0xF8) +            /* Extract Potenciometer Value */
           ((val >> 7) & 0x08);
//   PotVal = (val >> 6);
#else
  if ( ADC0IntDone )
  {
  	ADC0IntDone = 0;
	PotVal = ((ADC0Value >> 8) & 0xF8) +            /* Extract Potenciometer Value */
           ((ADC0Value >> 7) & 0x08);
//	PotVal = (ADC0Value >> 6);
  }
#endif
  return;
}


/*
 * Timer Counter 0 Interrupt Service Routine
 *   executed each 31.25us (32kHz frequency)
 */

void TIMER0_ISR (void) __irq {
  long  val;
  DWORD cnt;

#if !ADC_POLLING
	AD0CR |= (1 << 24 );
#endif

  if (DataRun) {                            /* Data Stream is running */
    val = DataBuf[DataOut];                 /* Get Audio Sample */
    cnt = (DataIn - DataOut) & (B_S - 1);   /* Buffer Data Count */
    if (cnt == (B_S - P_C*P_S)) {           /* Too much Data in Buffer */
      DataOut++;                            /* Skip one Sample */
    }
    if (cnt > (P_C*P_S)) {                  /* Still enough Data in Buffer */
      DataOut++;                            /* Update Data Out Index */
    }
    DataOut &= B_S - 1;                     /* Adjust Buffer Out Index */
    if (val < 0) VUM -= val;                /* Accumulate Neg Value */
    else         VUM += val;                /* Accumulate Pos Value */
    val  *= Volume;                         /* Apply Volume Level */
    val >>= 16;                             /* Adjust Value */
    val  += 0x8000;                         /* Add Bias */
    val  &= 0xFFFF;                         /* Mask Value */
  } else {
    val = 0x8000;                           /* DAC Middle Point */
  }

  if (Mute) {
    val = 0x8000;                           /* DAC Middle Point */
  }
  if ( !AudioON )
  {
    val = 0x8000;
  }

  DACR = val & 0xFFC0;                      /* Set Speaker Output */

  if ((Tick++ & 0x03FF) == 0) {             /* On every 1024th Tick */
    get_potval();                           /* Get Potenciometer Value */
    if (VolCur == 0x8000) {                 /* Check for Minimum Level */
      Volume = 0;                           /* No Sound */
    } else {
      Volume = VolCur * PotVal;             /* Chained Volume Level */
    }
    val = VUM >> 20;                        /* Scale Accumulated Value */
    VUM = 0;                                /* Clear VUM */
    if (val > 7) val = 7;                   /* Limit Value */
//    IOCLR2 = LEDMSK;                        /* Turn Off all LEDs */
//    IOSET2 = LEDMSK >> (7 - val);           /* LEDs show VU Meter */
  }

  T0IR = 1;                                 /* Clear Interrupt Flag */
  VICVectAddr = 0;                          /* Acknowledge Interrupt */
}


/* Main Program */

DWORD usbaudioInit(void) {

  PINSEL1 &= ~0x0030C000;	/* P0.23, A0.0, function 01, P0.26 AOUT, function 10 */
  PINSEL1 |= 0x00204000;
//  IODIR2  = LEDMSK;                         /* LED's defined as Outputs */

  /* Enable CLOCK into ADC controller */
  PCONP |= (1 << 12);

  AD0CR   = 0x00200E01;		/* ADC: 10-bit AIN0 @ 4MHz */
#if !ADC_POLLING
  AD0INTEN = 0x001;			/* Enable ADC0 */
  if ( install_irq( ADC0_INT, (void *)ADC0Handler, HIGHEST_PRIORITY ) == FALSE )
  {
	return (FALSE);
  }
#endif
  DACR    = 0x00008000;                     /* DAC Output set to Middle Point */

  /* Setup Timer Counter 0: Periodic Timer with Interrupt at DATA_FREQ Rate */
  T0MR0 = Fpclk/DATA_FREQ - 1;          /* TC0 Match Value 0 */
  T0MCR = 3;                                /* TCO Interrupt and Reset on MR0 */
  T0TCR = 1;                                /* TC0 Enable */

  /* Setup Timer Counter 0 Interrupt */
  install_irq( TIMER0_INT, (void *)TIMER0_ISR, HIGHEST_PRIORITY );

  USB_Init();                               /* USB Initialization */
  USB_Connect(TRUE);                        /* USB Connect */
  return ( TRUE );
}

⌨️ 快捷键说明

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