a
a
aa
Phone: (800) ANALOG-D, FAX: (781) 461-3010, EMAIL: dsp.support@analog.com, FTP: ftp.analog.com, WEB: www.analog.com/dsp
Engineer To Engineer Note EE-142
Technical Notes on using Analog Devices’ DSP components and development tools
Autobuffering, C and FFTs on the ADSP-218x
Submitted 8/2001 by DTL
This application note presents a technique for using autobuffering when bit-reversal is enabled within
the C FFT libraries. These techniques are demonstrated in a C-based data acquisition and spectral
analysis system which also presents a number of programming techniques such as : setting up hardware
and ports in C, setting up FFT buffers on the correct memory boundaries and double-buffering with
autobuffering. There is a corresponding VisualDSP project that accompanies this application note make sure you have downloaded this as well.
The ADSP-218x family of DSPs support serial port DMA functionality with a feature called
autobuffering. Autobuffering moves received data from the RX register into memory via a pre-assigned
set of DAG registers. Conversely, it moves data from memory to the TX register via another set of DAG
registers. The C compiler allows us reserve register sets I2 and I3 for autobuffering. To reserve these
registers, use the –reserve switch (for example, -reserve=-I2,I3) in the project options->compile>Additional Options.
The FFT functions in the C-runtime library use an addressing mode available in the DAG1 registers
called bit-reversal. This addressing mode is used to scramble/unscramble FFT data which greatly
increases the efficiency of the FFT itself. When this mode (bit-reversal) is enabled, all accesses to the
DAG1 registers result in a bit-reversed memory access. This means that the addresses stored in the
corresponding Ix register are flipped (i.e. low bits are now high bits and visa versa).
If the FFT function has enabled bit-reversal, and a new sample arrives in the RX register while
autobuffering is enabled, the autobuffering DAG access will be reversed too! This means that the
received word will not end up in the memory buffer that was set aside for autobuffering but rather
somewhere else in DM as the destination address was bit-reversed.
Since most applications use autobuffering and bit-reversal, this can present a dilemma. This application
note details a technique to avoid this problem without sacrificing performance on the DSP.
This implementation is designed to work in a C environment but can be easily adapted to work in a pure
assembly environment.
Before we get into the nuts and bolts, let's discuss what it is we're going to do here. Essentially, we will
be turning off autobuffering before the FFT begins and handling the function autobuffering normally
handles, manually. Once the FFT function has completed, we will re-enable autobuffering. This
approach is done in assembly language so the overhead of manually handling the interrupts during the
FFT will be minimal (i.e. 10 instructions/received sample).
Copyright 2001, Analog Devices, Inc. All rights reserved. Analog Devices assumes no responsibility for customer product design or the use or application of customers’ products or
for any infringements of patents or rights of others which may result from Analog Devices assistance. All trademarks and logos are property of their respective holders. Information
furnished by Analog Devices Applications and Development Tools Engineers is believed to be accurate and reliable, however no responsibility is as sumed by Analog Devices
regarding the technical accuracy of the content provided in all Analog Devices’ Engineer-to-Engineer Notes.
Step 1: Modifying the C Interrupt Vector Table
In the C environment, there is a file called 218x_int_tab.asm which contains the interrupt vector table for
C interrupts. This file can be found in the VisualDSP\218x\lib\src\libc_src directory. We're going to
need to modify this file so copy it to your project directory and include it in your VisualDSP project.
Whenever you include a library source file in your project, this code will take precedence over the
version stored in the C library file. This way, you can tailor certain components of the C library without
having to build an entirely new library file!
Once you have included this file in your VisualDSP project, open it up. You'll see each interrupt vector
which is placed in its own section using the .section command. If your LDF file does not these sections,
copy them from one of the stock 218x LDF files. The first step is to ensure all of the interrupt vectors
have 4 instructions. Because they are explicitly placed in memory using the C library LDF file, they
weren't required to be 4 instructions long. But, the stock LDF files group all these sections to together
and they will be linked contiguously so if they are not all 4 instructions long, the interrupt table will be
misaligned! The short of it is this : if a vector only has 3 instructions, add an RTI; at the end as filler.
.section/code IVirqe;
.global ___irqe;
___irqe:
DM(I4+=M7)=AX1;
AX1=SIGIRQE;
JUMP __lib_int_determiner;
RTI;
The next step is to determine which of the 4 types of serial transmissions in which you'll be using
autobuffering (i.e. SPORT0 Receive, SPORT0 Transmit, SPORT1 Receive, SPORT1 Transmit). Once
this has been determined, locate the appropriate interrupt vectors and replace them with the following
(for example):
.section/code IVsport0recv;
.global ___sport0recv;
___sport0recv:
JUMP SPORT0_RX_Interrupt;
RTI;
RTI;
RTI;
The function call name is arbitrary but you'll want a unique function call for each of the SPORT vectors
you replace. In the example above, we replaced the SPORT0 Receive interrupt. Essentially what we are
doing here is setting up the C environment to bypass the C interrupt dispatcher and call our own
assembly interrupt.
EE-142 Page 2
Technical Notes on using Analog Devices’ DSP components and development tools
Phone: (800) ANALOG-D, FAX: (781)461-3010, EMAIL: dsp.support@analog.com, FTP: ftp.analog.com, WEB: www.analog.com/dsp