• No results found

Periodic Signal Generation

5.5. PSEUDONOISE SEQUENCES 111

Figure 5.21: Autocorrelation of a length N = 31 sequence that is not a valid maximal length PN sequence.

Power spectrum of [3,1]s PN Sequence

(a)

Power spectrum of [4,1]s PN Sequence

(b)

Figure 5.22: Power spectral density estimate using pn_spec.m.

continuous waveform that follows the pattern of the desired PN sequence. We can do this by providing MATLAB with multiple data points per chip; a reasonable number that provides a very nice output is 20 data points per chip. This technique is exploited in the program pn_spec.m included on the bookware CD-ROM; it generates a very nice plot of the PSD of a PN sequence. See Figure 5.22. In particular, compare Figure 5.22(a) to Figure 5.16.

In this N = 7 example, both figures show that the fundamental frequency of the discrete components is 1/7 the frequency of the first zero of the envelope. This is because the period of the PN sequence is N = 7 times longer than the period of one chip.

We have provided programs in MATLAB for exploring the correlation properties and

112 CHAPTER 5. PERIODIC SIGNAL GENERATION spectral properties of PN sequences, and for generating any desired PN sequence for a given set of feedback taps. While some examples have been provided in the text and in the MATLAB programs, recall that massive tables of feedback taps for generating valid maximal length PN sequences are available in books such as [65] or online such as [66].

The more general of the two PN sequence generation programs is pngen2.m, and it can accept any number of feedback taps in the [r, n, p, q, . . . ]sformat we have used in this chapter.

The taps are provided as input fb to pngen2.m in row vector format, and the output of pngen2.m is the PN sequence specified by those feedback taps. If you’re generating long codes, be sure to use a semicolon at the end of the command line on which you call pngen2.m to keep the output from filling the screen and slowing down the program execution. The key part of the code for pngen2.m is given in Listing 5.12.

Listing 5.12: MATLAB program to generate PN sequences for a given set of feedback taps.

% perform one cycle of code generation

2 f o r i = 1 : N

The number of stages is r, and the program uses the vector fb to determine from which stages to perform the exclusive OR operation. Note that one entire period of the PN sequence is generated before the program exits and provides output, so this code would need to be modified for a real-time approach. That is, a real-time approach would output a single chip of the desired PN sequence each “tick” of the clock, and keep running for however many periods were needed.

Before continuing, it should be noted that the PN sequence generation programs we have provided implement shift registers in a brute force way for simplicity of the code. For example, the shift_reg variable is a memory array of length r, which is very wasteful since each stage of the shift register only needs to store a single-bit binary value. There are certainly more elegant techniques that can be used.

5.5.4 DSK Implementation in C

This chapter is a rather long one, and space limitations restrict what we can show here for the real-time generation of PN sequences on the DSK. We will show only one method of generating a PN sequence in real-time on the DSK, and provide some basic suggestions for how you might use it.

One of the first questions to be answered would be, “Do you really need to generate the PN sequence in real time?” If the desired sequence is not long, it would be more efficient to just store it in memory (this method is really just a look-up table implementation). This is always true for Barker sequences, which are not generated by an SRG, and are always

5.5. PSEUDONOISE SEQUENCES 113 relatively short in length. But for longer-length PN sequences, storing them in memory becomes impractical, and it is more efficient to just generate them with a DSP software SRG implementation.

Real-Time Considerations

Following the same method we’ve used in previous chapters, you can carefully modify “de-vectorized” MATLAB code to get an initial version of C code that will run in real-time on the DSK. Looking at Listing 5.12, for example, you would first remove the outer for loop to convert to a sample-by-sample (or, in this case, chip-by-chip) approach. In an earlier part of the code, you would have already have declared in memory an integer variable of sufficient size to hold shift_reg (that is, having at least r bits), and an appropriate variable for fb;

only a single bit would be needed for output since each chip of the PN sequence would be output individually in real-time. Note that by using an appropriate size of unsigned integer variable (such as Uint32 for an SRG up to 32 stages) in your C code for the shift register, you can take advantage of the highly efficient shift-right command. The basic approach from Listing 5.12 could then be used to output a given PN sequence (as determined by the feedback taps defined by fb) on a chip-by-chip basis. After getting such a “brute force”

method to work, the next step would be to implement a more elegant technique.

If you intend to use the PN sequence as part of a real-time program using one or more DSKs where the input and output go through the codec(s), don’t neglect the fact that the Fs/2 bandwidth limitation imposed by the sampling theorem also applies to the PN sequence if it (or data modulated by it) goes through the codec. For this reason, it may be prudent to include in your real-time PN sequence generation code a method of some kind for constraining the “chip rate” of 1/Tc to stay within the limits of the sampling theorem.

This brings up the question how to provide the output containing the real-time PN se-quence. While the PN sequence can be used to modify (i.e., “spread” or “de-spread”) input data as part of the desired DSP algorithm and output the result via the codec, we recognize that some users may want access to just the PN sequence itself. Therefore, we make the real-time PN sequence available as a digital output on the DSK, using the WriteDigitalOutputs function (see OMAPL138_Support_DSP.c or DSK6713_Support.c in the common_code direc-tory of the bookware CR-ROM). Note that the WriteDigitalOutputs function behaves a bit differently on the OMAP-L138 Experimenter Kit versus the C6713 DSK. On the OMAP-L138 Experimenter Kit, WriteDigitalOutputs sends signals to four digital output pins on the LCD connector J15. Specifically, four bits 0–3 (where bit 0 is the LSB) are sent to pins 6–9, respectively, of connector J15. Ground is available on that connector at pins 1, 5, and 10. On the C6713 DSK, WriteDigitalOutputs sends four bits 0–3 (where bit 0 is the LSB) to four user LEDs (LED 1 through LED 4, respectively) included on the board that are easily accessible. In either case, this allows the user to connect (e.g., with a test probe clip) to the digital output signal as desired.

Generating a Real-Time PN sequence

We show an example of C code for real-time generation of a PN sequence using the DSK.

The files necessary to run this application are provided in the ccs\PN directory of Chapter 5.

The primary file of interest is ISRs_LFSR.c, which contains various declarations and the interrupt service routine to perform the PN sequence generation algorithm. As this program is written, the PN sequence that is generated does not modify the input data in any way.

Data samples are brought in from the codec and output to the codec with no modification (i.e., a simple “talk-through”). The PN sequence is sent as a digital output as described above. The reader is free to modify the input data with the PN sequence as desired.

114 CHAPTER 5. PERIODIC SIGNAL GENERATION

An excerpt of the declaration section of the code is shown in Listing 5.13.

Listing 5.13: Declarations for the PN Generator code.

// implementing Galois 16 - bit LFSR x ^16 + x ^14 + x ^13 + x ^11 + 1

2#define LFSR LENGTH 16

#define LFSR BIT MASK ( ( 1 << LFSR LENGTH) − 1)

4#define LFSR XOR MASK ( ( ( 1 << 1 6 ) | (1 << 14) | (1 << 13) | [+] ( 1 << 1 1 ) ) >> 1 )

#define LFSR SEED VALUE 3

6

// reduce LFSR update rate to Fs / DIVIDE_BY_N

8#define DIVIDE BY N 10

10 Uint32 LSFR_reg = LFSR_SEED_VALUE ; An explanation of Listing 5.13 follows.

1. (Line 1): Note the SRG will be a Galois implementation, which has implications for how the feedback taps should be specified.

2. (Line 2): Declares the SRG to have 16 stages.

3. (Line 3): This mask is used in the ISR to set the SRG to the number of stages specified by line 1.

4. (Line 4): This is where you specify the feedback taps for the PN sequence you wish to generate. In this case, the PN sequence to be generated will be [16, 14, 13, 11]m, which produces a maximal-length sequence with a length of 65,535 chips. By simply changing this line and line 2, you can specify any PN sequence of up to 32 stages.

5. (Line 5): Determines the “seed state” for the SRG. It doesn’t matter what value is used here, as long as it’s not zero.

6. (Line 8): The factor by which the chip rate will be slowed compared to the sample frequency of the codec.

7. (Line 10): This 32-bit unsigned integer LFSR_reg is where the stages of the SRG are stored.

The algorithm section of the code is shown in Listing 5.14.

Listing 5.14: Algorithm for the PN Generator code.

interrupt void Codec_ISR ( )

2 {

/* add any local variables here */

4 Uint8 lsb ;

s t a t i c Int32 divide_by_n = 0 ; // used to slow PN rate

6

i f ( CheckForOverrun ( ) ) // overrun error occurred

8 return ; // so serial port is reset

10 CodecDataIn . UINT = ReadCodecData ( ) ; // get input data

12 /* add your code starting here */