1 |
/*---------------------------------------------------------------------------- |
---|
2 |
* Name: DEMO.C |
---|
3 |
* Purpose: USB Audio Demo |
---|
4 |
* Version: V1.10 |
---|
5 |
*---------------------------------------------------------------------------- |
---|
6 |
* This file is part of the uVision/ARM development tools. |
---|
7 |
* This software may only be used under the terms of a valid, current, |
---|
8 |
* end user licence from KEIL for a compatible version of KEIL software |
---|
9 |
* development tools. Nothing else gives you the right to use it. |
---|
10 |
* |
---|
11 |
* Copyright (c) 2005-2007 Keil Software. |
---|
12 |
*---------------------------------------------------------------------------*/ |
---|
13 |
|
---|
14 |
#include <LPC23XX.H> /* LPC23xx definitions */ |
---|
15 |
|
---|
16 |
#include "type.h" |
---|
17 |
#include "usb.h" |
---|
18 |
#include "usbcfg.h" |
---|
19 |
#include "usbhw.h" |
---|
20 |
#include "usbcore.h" |
---|
21 |
#include "demo.h" |
---|
22 |
|
---|
23 |
BYTE Mute; /* Mute State */ |
---|
24 |
DWORD Volume; /* Volume Level */ |
---|
25 |
|
---|
26 |
#if USB_DMA |
---|
27 |
#pragma arm section zidata = "USB_RAM" |
---|
28 |
DWORD InfoBuf[P_C]; /* Packet Info Buffer */ |
---|
29 |
short DataBuf[B_S]; /* Data Buffer */ |
---|
30 |
#pragma arm section zidata |
---|
31 |
#else |
---|
32 |
short DataBuf[B_S]; /* Data Buffer */ |
---|
33 |
#endif |
---|
34 |
|
---|
35 |
WORD DataOut; /* Data Out Index */ |
---|
36 |
WORD DataIn; /* Data In Index */ |
---|
37 |
|
---|
38 |
BYTE DataRun; /* Data Stream Run State */ |
---|
39 |
|
---|
40 |
WORD PotVal; /* Potenciometer Value */ |
---|
41 |
|
---|
42 |
DWORD VUM; /* VU Meter */ |
---|
43 |
|
---|
44 |
DWORD Tick; /* Time Tick */ |
---|
45 |
|
---|
46 |
|
---|
47 |
/* |
---|
48 |
* Get Potenciometer Value |
---|
49 |
*/ |
---|
50 |
|
---|
51 |
void get_potval (void) |
---|
52 |
{ |
---|
53 |
DWORD val; |
---|
54 |
|
---|
55 |
AD0CR |= 0x01000000; /* Start A/D Conversion */ |
---|
56 |
do { |
---|
57 |
val = AD0GDR; /* Read A/D Data Register */ |
---|
58 |
} while ((val & 0x80000000) == 0); /* Wait for end of A/D Conversion */ |
---|
59 |
AD0CR &= ~0x01000000; /* Stop A/D Conversion */ |
---|
60 |
PotVal = ((val >> 8) & 0xF8) + /* Extract Potenciometer Value */ |
---|
61 |
((val >> 7) & 0x08); |
---|
62 |
} |
---|
63 |
|
---|
64 |
|
---|
65 |
/* |
---|
66 |
* Timer Counter 0 Interrupt Service Routine |
---|
67 |
* executed each 31.25us (32kHz frequency) |
---|
68 |
*/ |
---|
69 |
|
---|
70 |
void tc0_isr (void) __irq |
---|
71 |
{ |
---|
72 |
long val; |
---|
73 |
DWORD cnt; |
---|
74 |
|
---|
75 |
if (DataRun) { /* Data Stream is running */ |
---|
76 |
val = DataBuf[DataOut]; /* Get Audio Sample */ |
---|
77 |
cnt = (DataIn - DataOut) & (B_S - 1); /* Buffer Data Count */ |
---|
78 |
if (cnt == (B_S - P_C*P_S)) { /* Too much Data in Buffer */ |
---|
79 |
DataOut++; /* Skip one Sample */ |
---|
80 |
} |
---|
81 |
if (cnt > (P_C*P_S)) { /* Still enough Data in Buffer */ |
---|
82 |
DataOut++; /* Update Data Out Index */ |
---|
83 |
} |
---|
84 |
DataOut &= B_S - 1; /* Adjust Buffer Out Index */ |
---|
85 |
if (val < 0) VUM -= val; /* Accumulate Neg Value */ |
---|
86 |
else VUM += val; /* Accumulate Pos Value */ |
---|
87 |
val *= Volume; /* Apply Volume Level */ |
---|
88 |
val >>= 16; /* Adjust Value */ |
---|
89 |
val += 0x8000; /* Add Bias */ |
---|
90 |
val &= 0xFFFF; /* Mask Value */ |
---|
91 |
} else { |
---|
92 |
val = 0x8000; /* DAC Middle Point */ |
---|
93 |
} |
---|
94 |
|
---|
95 |
if (Mute) { |
---|
96 |
val = 0x8000; /* DAC Middle Point */ |
---|
97 |
} |
---|
98 |
|
---|
99 |
DACR = val & 0xFFC0; /* Set Speaker Output */ |
---|
100 |
|
---|
101 |
if ((Tick++ & 0x03FF) == 0) { /* On every 1024th Tick */ |
---|
102 |
get_potval(); /* Get Potenciometer Value */ |
---|
103 |
if (VolCur == 0x8000) { /* Check for Minimum Level */ |
---|
104 |
Volume = 0; /* No Sound */ |
---|
105 |
} else { |
---|
106 |
Volume = VolCur * PotVal; /* Chained Volume Level */ |
---|
107 |
} |
---|
108 |
val = VUM >> 20; /* Scale Accumulated Value */ |
---|
109 |
VUM = 0; /* Clear VUM */ |
---|
110 |
if (val > 7) val = 7; /* Limit Value */ |
---|
111 |
FIO2CLR = LEDMSK; /* Turn Off all LEDs */ |
---|
112 |
FIO2SET = LEDMSK >> (7 - val); /* LEDs show VU Meter */ |
---|
113 |
} |
---|
114 |
|
---|
115 |
T0IR = 1; /* Clear Interrupt Flag */ |
---|
116 |
VICVectAddr = 0; /* Acknowledge Interrupt */ |
---|
117 |
} |
---|
118 |
|
---|
119 |
|
---|
120 |
/* Main Program */ |
---|
121 |
|
---|
122 |
int main (void) |
---|
123 |
{ |
---|
124 |
PINSEL10 = 0; /* Disable ETM Interfaces */ |
---|
125 |
PINSEL1 = 0x00204000; /* Select AOUT,AIN0 */ |
---|
126 |
FIO2DIR = LEDMSK; /* P2[0..7] = Output only */ |
---|
127 |
|
---|
128 |
PCONP |= (1 << 12); /* Enable power to AD block */ |
---|
129 |
AD0CR = 0x00200E01; /* ADC: 10-bit AIN0 @ 4MHz */ |
---|
130 |
DACR = 0x00008000; /* DAC Output set to Middle Point */ |
---|
131 |
|
---|
132 |
/* Setup Timer Counter 0: Periodic Timer with Interrupt at DATA_FREQ Rate */ |
---|
133 |
T0MR0 = VPB_CLOCK/DATA_FREQ - 1; /* TC0 Match Value 0 */ |
---|
134 |
T0MCR = 3; /* TCO Interrupt and Reset on MR0 */ |
---|
135 |
T0TCR = 1; /* TC0 Enable */ |
---|
136 |
|
---|
137 |
/* Setup Timer Counter 0 Interrupt */ |
---|
138 |
VICVectAddr4 = (unsigned long)tc0_isr; /* TC0 Interrupt -> Vector 4 */ |
---|
139 |
VICVectCntl4 = 0x02; /* TC0 Interrupt -> Priority 2 */ |
---|
140 |
VICIntEnable = 1 << 4; /* Enable TC0 Interrupt */ |
---|
141 |
|
---|
142 |
USB_Init(); /* USB Initialization */ |
---|
143 |
USB_Connect(TRUE); /* USB Connect */ |
---|
144 |
|
---|
145 |
while (1); /* Loop forever */ |
---|
146 |
} |
---|