ECE 320 Spring 2004 by Mark Butala, et al - HTML preview

PLEASE NOTE: This is an HTML preview only and some elements such as links or page numbers may be incorrect.
Download the book in PDF, ePub for a complete version.

17

18 // Initial PN generator register contents

19 int seed = 1;

20

21 // Initial phase

22 int prev_phase = 0;

23

24

25 while( 1 )

26 {

27 /* Wait for a new block of samples */

28 WaitAudio(&Rcvptr,&Xmitptr);

29

30 // Get next two random bits

31 r1 = randbit( &seed );

32 r2 = randbit( &seed );

33 // Convert 2 bit binary number to decimal

34 symbol = series2parallel(r1,r2);

35

36 for (n=0; n<32; n++)

37 {

38 phase[n] = ( freqs[symbol]*n + prev_phase ) % 64; // get into 0 to 64 range

39 if (phase[n] > 32) phase[n]=phase[n]-64; // get into -32 to 32 range

40 phase[n] = phase[n] * 1024; // 1024=2^15*1/32

41 // [-2^15 2^15] range for use with

42 // SINE.asm

43 }

44 sine(&phase[0], &output[0], 32); // compute SINE, put result in output[0 -

31]

45 prev_phase = ( freqs[symbol]*32 + prev_phase ) % 64; // save current phase offset

46

47 // Get next two random bits

48 r1 = randbit( &seed );

49 r2 = randbit( &seed );

50 // Convert 2 bit binary number to decimal

51 symbol = series2parallel(r1,r2);

52

53 for (n=0; n<32; n++)

54 {

55 phase[n] = ( freqs[symbol]*n + prev_phase ) % 64;

56 if (phase[n] > 32) phase[n]=phase[n]-64;

57 phase[n] = phase[n] * 1024;

58 }

59 sine(&phase[0], &output[32], 32);

60 prev_phase = ( freqs[symbol]*32 + prev_phase ) % 64;

61

62

63 // Transfer the two symbols to transmit buffer

64 for (n=0; n<64; n++)

65 {

66 Xmitptr[6*n] = output[n];

67 }

68

69 }

70 }

71

72

73 // Converts 2 bit binary number (r2r1) to decimal

74 int series2parallel(int r2, int r1)

75 {

76 if ((r2==0)&&(r1==0)) return 0;

77 else if ((r2==0)&&(r1==1)) return 1;

78 else if ((r2==1)&&(r1==0)) return 2;

79 else return 3;

80 }

81

82 //Returns as an integer a random bit, based on the 15 low-significance bits in iseed (which is

83 //modified for the next call).

84 int randbit(unsigned int *iseed)

85 {

86 unsigned int newbit; // The accumulated XORs.

87 newbit = (*iseed >> 14) & 1 ^ (*iseed >> 13) & 1; // XOR bit 15 and bit 14

88 // Leftshift the seed and put the result of the XORs in its bit 1.

89 *iseed=(*iseed << 1) | newbit;

90 return (int) newbit;

91 }

Solutions

index-64_1.jpg

index-64_2.jpg

Chapter 2. Project Labs

2.1. Adaptive Filtering

Adaptive Filtering: LMS Algorithm*

Introduction

Figure 2.1 is a block diagram of system identification using adaptive filtering. The objective is to change (adapt) the coefficients of an FIR filter, W , to match as closely as possible the response of

an unknown system, H . The unknown system and the adapting filter process the same input signal

x[ n] and have outputs d[ n] (also referred to as the desired signal) and y[ n] .

Figure 2.1.

System identification block diagram.

Gradient-descent adaptation

The adaptive filter, W , is adapted using the least mean-square algorithm, which is the most

widely used adaptive filtering algorithm. First the error signal, e[ n] , is computed as

e[ n]= d[ n]− y[ n] , which measures the difference between the output of the adaptive filter and the output of the unknown system. On the basis of this measure, the adaptive filter will change its

coefficients in an attempt to reduce the error. The coefficient update relation is a function of the

error signal squared and is given by

()

The term inside the parentheses represents the gradient of the squared-error with respect to the

i th coefficient. The gradient is a vector pointing in the direction of the change in filter coefficients

index-65_1.jpg

index-65_2.jpg

that will cause the greatest increase in the error signal. Because the goal is to minimize the error,

however, Equation updates the filter coefficients in the direction opposite the gradient; that is why the gradient term is negated. The constant μ is a step-size, which controls the amount of gradient

information used to update each coefficient. After repeatedly adjusting each coefficient in the

direction opposite to the gradient of the error, the adaptive filter should converge; that is, the

difference between the unknown and adaptive systems should get smaller and smaller.

To express the gradient decent coefficient update equation in a more usable manner, we can

rewrite the derivative of the squared-error term as

()

()

which in turn gives us the final LMS coefficient update,

()

h n+1[ i]= hn[ i]+ μex[ ni]

The step-size μ directly affects how quickly the adaptive filter will converge toward the unknown

system. If μ is very small, then the coefficients change only a small amount at each update, and

the filter converges slowly. With a larger step-size, more gradient information is included in each

update, and the filter converges more quickly; however, when the step-size is too large, the

coefficients may change too quickly and the filter will diverge. (It is possible in some cases to

determine analytically the largest value of μ ensuring convergence.)

MATLAB Simulation

Simulate the system identification block diagram shown in Figure 2.1.

Previously in MATLAB, you used the filter command or the conv command to implement

shift-invariant filters. Those commands will not work here because adaptive filters are shift-

varying, since the coefficient update equation changes the filter's impulse response at every

sample time. Therefore, implement the system identification block on a sample-by-sample basis

with a do loop, similar to the way you might implement a time-domain FIR filter on a DSP. For

the "unknown" system, use the fourth-order, low-pass, elliptical, IIR filter designed for the IIR

Filtering: Filter-Design Exercise in MATLAB.

Use Gaussian random noise as your input, which can be generated in MATLAB using the

command randn. Random white noise provides signal at all digital frequencies to train the

adaptive filter. Simulate the system with an adaptive filter of length 32 and a step-size of 0.02 .

Initialize all of the adaptive filter coefficients to zero. From your simulation, plot the error (or

squared-error) as it evolves over time and plot the frequency response of the adaptive filter

coefficients at the end of the simulation. How well does your adaptive filter match the "unknown"

filter? How long does it take to converge?

Once your simulation is working, experiment with different step-sizes and adaptive filter lengths.

Processor Implementation

Use the same "unknown" filter as you used in the MATLAB simulation.

Although the coefficient update equation is relatively straightforward, consider using the lms

instruction available on the TI processor, which is designed for this application and yields a very

efficient implementation of the coefficient update equation.

To generate noise on the DSP, you can use the PN generator from the Digital Transmitter:

Introduction to Quadrature Phase-Shift Keying, but shift the PN register contents up to make the sign bit random. (If the sign bit is always zero, then the noise will not be zero-mean and this

will affect convergence.) Send the desired signal, d[ n] , the output of the adaptive filter, y[ n] , and the error to the D/A for display on the oscilloscope.

When using the step-size suggested in the MATLAB simulation section, you should notice that the

error converges very quickly. Try an extremely small μ so that you can actually watch the

amplitude of the error signal decrease towards zero.

Extensions

If your project requires some modifications to the implementation here, refer to Haykin [link] and consider some of the following questions regarding such modifications:

How would the system in Figure 2.1 change for different applications? (noise cancellation,

equalization, etc. )

What happens to the error when the step-size is too large or too small?

How does the length of an adaptive FIR filters affect convergence?

What types of coefficient update relations are possible besides the described LMS algorithm?

References

1. S. Haykin. (1996). Adaptive Filter Theory. (3rd edition). Prentice Hall.

index-67_1.jpg

2.2. Audio Effects

Audio Effects: Real-Time Control with the Serial Port*

Implementation

For this exercise, you will extend the system from Audio Effects: Using External Memory to generate a feedback-echo effect. You will then extend this echo effect to use the serial port on the

DSP EVM. The serial interface will receive data from a MATLAB GUI that allows the two system

gains and the echo delay to be changed using on-screen sliders.

Feedback system implementation

Figure 2.2.

Feedback System with Test Points

First, modify code from Audio Effects: Using External Memory to create the feedback-echo system shown in Figure 2.2. A one-tap feedback-echo is a simple audio effect that sounds

remarkably good. You will use both channels of input by summing the two inputs so that either or

both may be used as an input to the system. Also, send several test signals to the six-channel

board's D/A converters:

The summed input signal

The input signal after gain stage G 1

The data going into the long delay

The data coming out of the delay

You will also need to set both the input gain G 0 and the feedback gain G 1 to prevent overflow.

As you implement this code, ensure that the delay n and the gain values G 1 and G 2 are stored in

memory and can be easily changed using the debugger. If you do this, it will be easier to extend

your code to accept its parameters from MATLAB in MATLAB Interface Implementation.

To test your echo, connect a CD player or microphone to the input of the DSP EVM, and connect

the output of the DSP EVM to a loudspeaker. Verify that an input signal echoes multiple times in

the output and that the spacing between echoes matches the delay length you have chosen.

MATLAB interface implementation

After studying the MATLAB interface outlined at the end of Using the Serial Port with a

MATLAB GUI, write MATLAB code to send commands to the serial interface based on three sliders: two gain sliders (for G 1 and G 2 ) and one delay slider (for n). Then modify your code to

accept those commands and change the values for G 1 , G 2 and n. Make sure that n can be set to

values spanning the full range of 0 to 131,072, although it is not necessary that every number in

that range be represented.

Audio Effects: Using External Memory*

Introduction

Many audio effects require storing thousands of samples in memory on the DSP. Because there is

not enough memory on the DSP microprocessor itself to store so many samples, external memory

must be used.

In this exercise, you will use external memory to implement a long audio delay and an audio echo.

Refer to Core File: Accessing External Memory on TI TMS320C54x for a description and examples of accessing external memory.

Delay and Echo Implementation

You will implement three audio effects: a long, fixed-length delay, a variable-length delay, and a

feedback-echo.

Fixed-length delay implementation

First, implement the 131,072-sample delay shown in Figure 2.3 using the READPROG and

WRITPROG macros. Use memory locations 010000h-02ffffh in external Program RAM to do

this; you may also want to use the dld and dst opcodes to store and retrieve the 32-bit addresses

for the accumulators. Note that these two operations store the words in memory in big-endian

index-69_1.jpg

index-69_2.jpg

order, with the high-order word first.

Figure 2.3.

Fixed-Length Delay

Remember that arithmetic operations that act on the accumulators, such as the add instruction,

operate on the complete 32- or 40-bit value. Also keep in mind that since 131,072 is a power of

two, you can use masking (via the and instruction) to implement the circular buffer easily. This

delay will be easy to verify on the oscilloscope. (How long, in seconds, do you expect this delay to

be?)

Variable-delay implementation

Once you have your fixed-length delay working, make a copy and modify it so that the delay can

be changed to any length between zero (or one) and 131,072 samples by changing the value stored

in one double-word pair in memory. You should keep the buffer length equal to 131,072 and

change only your addressing of the sample being read back; it is more difficult to change the

buffer size to a length that is not a power of two.

Verify that your code works as expected by timing the delay from input to output and ensuring

that it is approximately the correct length.

Feedback-echo implementation

Last, copy and modify your code so that the value taken from the end of the variable delay from

Variable-delay implementation is multiplied by a gain factor and then added back into the input, and the result is both saved into the delay line and sent out to the digital-to-analog converters.

Figure 2.4 shows the block diagram. (It may be necessary to multiply the input by a gain as well to prevent overflow.) This will make a one-tap feedback echo, an simple audio effect that sounds

remarkably good. To test the effect, connect the DSP EVM input to a CD player or microphone

and connect the output to a loudspeaker. Verify that the echo can be heard multiple times, and that

the spacing between echoes matches the delay length you have chosen.

Figure 2.4.

Feedback Echo

index-70_1.jpg

2.3. Communications

Communications: Using Direct Digital Synthesis*

Introduction

Direct Digital Synthesis ( DDS) is a method for generating a desired waveform (such as a sine

wave) by using the technique described in Figure 2.5 below.

Figure 2.5.

Direct digital synthesis (DDS) ( Couch [link])

Quantized samples of a desired waveform are stored in the memory of the microprocessor system.

This desired waveform can then be generated by "playing out" the stored words into the digital-to-

analog converter. The frequency of this waveform is determined simply by how fast the stored

words are read from memory, and is thus programmable. Likewise, the phase and amplitude of the

generated waveform are programmable.

The DDS technique is replacing analog circuits in many applications. For example, it is used in

higher-priced communication receivers to generate local oscillator signals. It can also be used to

generate sounds in electronic pipe organs and music synthesizers. Another application is its use by

lab instrument manufacturers to generate output waveforms in function generators and arbitrary

waveform generators ( Couch [link]).

In this lab you will familiarize yourself with the capabilities of the Analog Devices AD9854 DDS.

The DDS board is installed between the 6-channel card and the DSP card at some (not all) lab

stations. You can tell which boxes have them by the way the 6-channel card sits higher inside the

metal box.

Frequency Modulation (FM) Radio Exercise

index-71_1.jpg

To get your feet wet and see a demonstration of the DDS, perform the following exercise. Copy

the files FM.asm (downloadable here) and mod.asm from the v:\ece320\54x\dds\

directory. Assemble and run the frequency modulation (FM) program FM.asm. Next, plug an

audio source into one of the two DSP input channels that you've been using all semester. If you

have a CD on you, pop it into the computer and use that. If not, use a music web site on the

Internet as your audio source. Connect the computer to the DSP by using a male-male audio cable

and an audio-to-BNC converter box (little blue box), both of which are in the lab. The computer

has three audio outputs on the back; use the middle jack. Ask your TA if you can't find the cable

and/or box or don't see how to make the connection. Next, connect a dipole antenna to the output

of the DDS (port \#1 on the back of the DDS board). A crude but effective dipole antenna can be

formed by connecting together a few BNC and banana cables in the shape of a T. There should be

one or two of these concoctions in the lab. Once the connections are made, turn on the black

receiver in the lab, and tune it to 104.9 MHz (wide band FM). You should be able to hear your

audio source!

If your audio sounds distorted, it's most likely due to the volume of your audio source being

too loud and getting clipped by the DSP analog-to-digital converter.

Spectral Copies

Spectral Copies: The digital-to-analog converter on the DDS is unfiltered, which means that there

is no anti-imaging filter to remove the spectral replicas. To see this, plug the output of the DDS

board directly into the vector signal analyzer (VSA), and observe the spectrum. Use 104.9 MHz as

the center frequency, and set the span wide enough so that you can see the spectra of the replicas

to the left and right of the 104.9 MHz signal. Use the marker to find the peaks of the other

replicas, and record their frequencies. Once you've done that, reattach the antenna to the DDS

output, and tune the receiver to the frequencies you just recorded. You should be able to hear your

audio on each of the other frequencies.

Note

The clock rate of the DDS is 60MHz, which corresponds to 2 π in digital frequency.

Therefore, the 104.9 MHz signal you just listened to is roughly equivalent to

in digital

frequency. What are the digital frequencies of the other copies you saw on the VSA?

How to use the DDS

index-72_1.jpg

The DDS has several different modes of operation: single-tone, unramped Frequency Shift

Keying ( FSK), ramped FSK, chirp, and Binary Phase Shift Keying ( BPSK). In this lab we will

use the DDS in single-tone mode. Single-tone mode is easy to use, and is powerful enough to

create many different kinds of waveforms, including FM and FSK.

FM code

The FM code you just ran (also listed here) is fairly straightforward. The program first calls the

radioinit subroutine. This routine sets the DDS to single-tone mode and turns off an inverse-

sinc filter to conserve power. Following radioinit, the setcarrier subroutine is called.

This routine sets the frequency of the DDS output by writing to the two most significant 8-bit

frequency registers of the 48-bit frequency-tuning word on the DDS[3]. Although the frequency-

tuning word on the DDS has 48 bits of resolution, the upper 16 bits provide us with enough

resolution for the purposes of this lab, and so we will only be writing to the two most significant

registers. See page 26 in the DDS data sheet for a layout of the frequency-tuning word.

To set the carrier frequency, we first need to determine what frequency word has to be written to

the frequency registers on the DDS. This can be done using Equation:

()

where baseband frequency corresponds to the desired frequency that lies in the range of 0-30

MHz. For example, to get the DDS to transmit at 104.9 MHz, you would choose the baseband

frequency to be 15.1 MHz since 104.9 MHz is one of the unfiltered spectral replicas of 15.1 MHz.

Then, using Equation, the frequency word for 15.1 MHz (and 104.9 MHz) would be equal to 406D

3A06 D3D4h. But since we only write to the two most significant registers of the frequency-

tuning word, we only need the first 4 hexadecimal numbers of this result, i.e. 406Dh. The first

two of those, 40h, need to get written to the most significant 8-bit frequency register, while the

second two hex numbers, 6Dh, need to get written to the second-most significant 8-bit frequency

register. This is where the 40h and 6Dh in the setcarrier subroutine of the FM code come

from.

Writing to the frequency registers is accomplished using the portw instruction. To write to the

frequency or phase registers on the DDS, the second operand of the portw instruction must be

10xxxxxx, where the lower six bits are the address of the specific register to be written to. The

address of the most significant frequency register on the DDS is 04h, and the address of the

second most significant frequency register on the DDS is 05h (see page 26 in the data sheet). It is

important to note that the way our DDS boards were built, you will not be allowed to make two