|
|
CD2458 Tutorial
Program Example (Automatic
Gain Control)
This example gives
an AGC function to keep the output power constant for an input varying
-43dB to 0dB. If you do not have enough knowledge about the feed back
loop, you would probably think "Let's make something and determine
the parameters with experiment.". This example is made for such engineers.
(Fig.1)
Let's assume the input
signal amplitude changes from 0 to +/- 0.25 in average, and the peak input
value is smaller than +/- 0.9. This is just for your easy understanding
of this example.
There is unknown signal
level that should be amplified to keep the best dynamic range at post
process. First, you need to know long term average power of the input
signal, then gradually change the gain of the amplifier so that the output
from the amplifier keeps necessary average power. The output signal level
from the AGC may be set to high level with that the post process will
have easier data handling.
How do you get the
average power of the input signal? If you have big memory for AGC, you
might store every input signal sample squared in the memory, and calculate
the average power by adding N pieces of stored data. The oldest sample(s)
will be discarded for new sample(s) input after the calculation. If you
take large N, the time constant of the AGC may be big, whereas short time
constant is expected with small N. This method needs ridiculously big
resource consumption: N word memory and N times addition for every computation.
You may need to compromise in this part for better cost performance.

Flow Chart

As usual, let's assume
a simple "interrupt driven routine" for AGC. The AGC program works only
at an interrupt, and the DSP gets into an idle state to wait for next
interrupt once the interrupt service routine is executed. During the interrupt
service, one new input sample is read and one output datum goes out at
the beginning, then the "GAIN control" routine will be executed
for next output (input x GAIN) calculation.
The Fig.2 shows a
flow chart for the AGC part of interrupt service routine. If you are working
on an Audio frequency application, you might have only 22.6uS between
interrupts. Assuming 20MHz operation, there is only about 450 cycles of
instruction execution time. Although you do not need to run the AGC service
routine at every interrupt as a compromise, we'll assume the AGC routine
runs at every interrupt just for easier programming.
The GAIN increment/decrement
parameter determines the time constant of the AGC in this example program.
You can find out your best time constant with an experiment. You should
try impulse noise, continuous wave, 0dB -> -50dB, -50dB ->0dB, signals
periodically changing its amplitude in various frequency, etc.. Do you
see unstable conditions at any of those input forms?

Program List
#
#
#
# AGC Examples For CD2458
# (c)2002 Clarkspur Design, Inc.
#
Initialize:
0000 08C0 00FF LDI SP,'hff
0002 0844 0001 0001 LDLI ST,'h010001
0005 0810 2000 LDI ah,'h2000
0007 5021 OUTD 'h2,ah # Enable 44.1KHz interrupt
0008 0838 1E00 LDI r3,'h1E00
000A 0938 0100 LDI r7,'h100
000C 54B0 MODF ie3
stayhere:
#call @INT2service
000D 4C00 000D BRA @stayhere
INT2service:
000F EE4A TGL st,'ha
0010 4800 0048 CALL @IO
0012 0021 LD x,ah
0013 0601 LD a,001
0014 0031 LD y,ah
0015 0017 LD ah,ph
0016 4602 LD 002,A
0017 4800 001D CALL @GAIN
0019 0602 LD A,002
001A 3077 SHA 'h37 #SHA -9
001B 54B0 MODF ie3
001C 015C RET
GAIN:
001D 3046 SHA 6
001E 9050 MOD abs #Compromized from squared to abs.
001F 9170 SWAP
0020 0600 LD a,000
0021 304F SHA 'hF
0022 00A1 LD tl,ah
0023 9170 SWAP
0024 4313 LD (r7),ah
0025 16FB MODR r7+,r3-
0026 4C01 002C BRA @SK1,nrz
0028 0838 1E00 LDI r3,'h1E00
002A 0938 0100 LDI r7,'h100
SK1:
002C 8600 ADD a,000
002D 9020 MOD sat
002E 200A SUB a,tl
002F 4600 LD 000,a
0030 6801 1000 CMPI a,'h1000,,,fl
0032 4C0F 0043 BRA @SK2,neg
0034 0601 LD a,001
0035 2800 0030 SUBI a,'h0030
SK4:
0037 4C07 003B BRA @SK6,pos
0039 0810 0010 LDI ah,10
SK6:
003B 6801 4000 CMPI a,'h4000,,,fl
003D 4C0F 0041 BRA @SK3,neg
#LDI ah,'h4000,,,fl
003F 0811 DW 'h0811
0040 4000 DW 'h4000
SK3:
0041 4601 LD 001,a
0042 015C RET
SK2:
0043 0601 LD a,001
0044 8800 0030 ADDI a,'h0030
0046 4C00 0037 BRA @SK4
IO:
0048 3048 SHA 'h8 #IO codec on LSB 16 bits
0049 5001 OUTD 0,ah
004A 1010 INPD ah,0
004B 3078 SHA 'h38 #SHA -8 IO codec on LSB 16 bits
004C 015C RET
FFFC org 'hfffc
FFFC 0000 dw @Initialize
FFFD 000F dw @INT2service
FFFE 000F dw @INT2service
FFFF 000F dw @INT2service
|