audio_doc
6.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
AI CONTROLLER PROGRAMMING INTERFACE
Operation:
################################################################################
On reset, the audio output register is cleared to zero to avoid a pop.
Internal state is also cleared to zero on reset to effectivly disable
audio on power up. (dac_rate, bit_rate, dma address, dma length are all reset)
External audio clock is held at zero, and audio word select is held at 1 (left
channel) after reset.
Once the dac rate and bit rate are is programmed,
the internal state machines kick off and the 32 bit current audio output is
repeatedly cycled out to the dac. This value will be zero after reset.
To enable the internal dma engine, the dma enable bit must be set in the
audio control register. Clearing dma enable during processing will stop
all dma requests. Audio output is not disrupted and the current output
sample will by repeatedly output.
Through this mechanism, the audio can be forced to quit requesting dma
transactions.
Audio DMA's are requested by writing the dma address, and dma length
registers to point the dma engine at audio samples. These double buffered
registers allow 2 samples to be requested.
The status register provides a FULL bit indicating both buffers are
currently occupied. The audio interrupt also serves to indicate to the
cpu a that a buffer has freed.
The audio dma's are broken up into a series of 8byte memory read
requests.
The audio interrupt is generated when the length register is decremented to
zero indicating the last 8 bytes of a requested dma are being fetched.
At this point, sw may issue the next dma request.
Soft Reset
Setting the bit_rate to zero will perform an internal soft reset.
Audio ouptut clocks will stop and audio output data will be zero.
The active length reg will also be set to zero which will
flush any queued up audio dma's from occuring.
The basic flow loop is
initialize audio timing registers
AI_CONTROL_REG
AI_DACRATE_REG
AI_BITRATE_REG
write address to AI_DRAM_ADDR_REG
write length to AI_LEN_REG
loop_forever {
write address
write length
while (bit_31_of_status == 1) wait;
(or when not interrupted by ai wait)
}
note: the address must be written before the length
Register Details:
################################################################################
The ai controller has 5 writeable registers and 2 readable registers as
follows:
AI_DRAM_ADDR_REG 0x0450_0000 dram address (write)
[23:0] starting RDRAM address
write only DMA byte address.
All DMA requests will be 8-byte aligned (3 lsbs = 0)
This register is double buffered
AI_LEN_REG 0x0450_0004 length (read/write)
[14:0] RCP1.0 transfer length
[17:0] RCP2.0
read/write DMA length in bytes.
All DMA buffers must be multiples of 8 bytes in length.
3 lsb's = 0
This register is double buffered, the Active register is the readable one.
This length register is decremented with each dma transaction. The
value returned on a read is the number of dma bytes remaining in the
current dma transaction.
If bit_rate register == 0, length register is cleared to zero
AI_CONTROL_REG 0x0450_0008 DMA enable (write only)
[0] dma_enable
If the LSB == 1 then DMA is enabled.
This register is set to zero on reset.
The DMA engine can be shut-down by clearing dma_enable
irregardless of current length.
AI_STATUS_REG 0x0450_000c status (read/write-clear)
(write) [] clear interrupt
any write to the status register will clear the audio interrupt.
(read)
read status word
* sw useful bits
*31 FULL length2_loaded_flag,
*30 BUSY !length_zero,
29 0
28 0
27 dma_busy,
26 dma_request,
25 dma_enable,
24 1'b1
23 dfifo2_loaded_flag,
22 data_available_flag,
21 word_select,
20 1'b1,
19 abus_word_2,
18 0
17 0
16 state[0] = bit clock
15 0
14 dac_cntr[13]
13 dac_cntr[12]
12 dac_cntr[11]
11 dac_cntr[10]
10 dac_cntr[09]
9 dac_cntr[08]
8 dac_cntr[07]
7 dac_cntr[06]
6 dac_cntr[05]
5 dac_cntr[04]
4 dac_cntr[03]
3 dac_cntr[02]
2 dac_cntr[01]
1 dac_cntr[00]
0 FULL length2_loaded_flag
AI_DACRATE_REG 0x0450_0010 audio dac period (write)
[13:0] vclk_divider_minus_1
DAC sample period register
vid_clock/(dperiod + 1) is the DAC sample rate
(dperiod + 1) >= 66 * (aclockhp + 1) must be true
This register is cleared on reset.
AI_BITRATE_REG 0x0450_0014 audio dac bit clock half period (write)
[3:0] vclk_divider_minus_1
abus clock half period register (aclockhp)
vid_clock/(2 * (aclockhp + 1)) is the DAC clock rate
The abus clock stops if aclockhp is zero.
The DMA length register is cleared if aclockhp is zero.
The dac_cntr is cleared if the bit_rate is zero.
This register is cleared on reset.
################################################################################
Audio Frequency Programming/Error 2/23/95
video_clk audio ratio divider error
48681810 44100 1103.895918 1104 94 ppm
49656530 44100 1125.998413 1126 1 ppm
48681810 32000 1521.306562 1522 456 ppm
49656530 32000 1551.766562 1552 150 ppm
#include "rcp.h"
...
/* Init VI to get video clock signal into AI */
dgWriteWord(VI_STATUS_REG, 0);
/* To get ~44.1 KHz for audio (based on Rambus clock of 243.37 MHz
* and video clock of 48.67 MHz), AI dac rate = 1103 (0x44f) and
* AI bit rate = 15 (0xf)
*/
dgWriteWord(AI_DACRATE_REG, 0x44f);
dgWriteWord(AI_BITRATE_REG, 0xf);
dgWriteWord(AI_CONTROL_REG, AI_CONTROL_DMA_ON);
################################################################################
Notes on Testing
> if i want to beat up the length register,
> can i write length, read length, write length , read length ....
> without screwing up a state machine? assume i have not set dma enable.
1st, if the bit_rate register is zero, then the length register is
reset to zero. So first you need to set the bit_rate reg != 0.
2nd problem is that the length register is double buffered.
you normally never see the second length until the first one counts down
to zero.
what you can do is to set the bit_rate reg to zero and back to non-zero
between write/reads to the length register to flush the dbl buffer.
################################################################################