Analog Devices EE188 Application Notes

Engineer To Engineer Note EE-188
Technical Notes on using Analog Devices' DSP components and development tools
a
Using C To Implement Interrupt-Driven Systems On ADSP-219x DSPs
Contact our technical support by phone: (800) ANALOG-D or e-mail: dsp.support@analog.com Or visit our on-line resources http://www.analog.com/dsp and http://www.analog.com/dsp/EZAnswers

Introduction

(timer_on, timer_off, and timer_set), which were created to make life for the C developer a little
This Engineer-to-Engineer note will describe the process for implementing a timer routine for the ADSP-219x family of DSPs using the C programming language. Please refer to chapter 12 of the “ADSP-219x DSP Hardware Reference” for further details regarding the timers.
The referenced code in this application note was verified using VisualDSP++™ 3.0 for ADSP-21xx DSPs and revision 2.0 of the ADDS-2191-EZLITE development board.
easier. In an ADSP-219x-based project, these functions no longer apply because now there are THREE possible sets of timer registers to associate these functions to, the registers for programming the timers are different, and the register memory space is also changed significantly from the ADSP-218x family of DSPs. Additionally, the 32-bit period, width, and count timer registers are now broken into low and high words, giving the ADSP-219x timers 65536 times the duration that the ADSP­218x timer had.

ADSP-219x Family Timers

Contrary to the ADSP-218x family of Digital Signal Processors (DSPs), the ADSP­219x family has three timers, each of which can be configured in any of three modes. On the assembly level, configuration of the timers and use of interrupts is fairly straightforward. However, in C, using interrupts and accessing the timer registers requires knowledge of some of the system header files and an understanding of how the C run-time environment works with embedded DSP programs. The process explained herein describes how to implement an interrupt-driven timer routine in C but the methods used can be applied to any C-coded interrupt routines.
The ADSP-218x C libraries defined three C-callable functions for timer management
Copyright 2003, 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 assumed by Analog Devices regarding the technical accuracy and topicality of the content provided in all Analog Devices’ Engineer-to-Engineer Notes.

Using Features In VisualDSP++

VisualDSP++ 3.0 comes equipped with several built-in, or intrinsic, functions designed to make programming a DSP in a C environment even more user-friendly.
Formerly, memory-mapped registers were accessed by a referencing-dereferencing scheme using casted pointers (*(int *)). Access to non-memory-mapped registers in C was a tedious task, requiring embedded assembly source code. Now, the intrinsic functions sysreg_read and sysreg_write are available for manipulating these registers. In addition to these system register functions, the ADSP-219x tools feature two other intrinsic functions, io_space_read and io_space_write, which provides access to all the memory-mapped I/O space registers as well.
a
These four functions are defined in the header file sysreg.h. In this header, there is also an enumerated type, listing the system registers that can be accessed using sysreg_read and sysreg_write. One will also find all the bit manipulation instructions here as well (sysreg_bit_clr, sysreg_bit_set, sysreg_bit_tgl).
The io_space_read and io_space_write intrinsic functions require the architecture definition header file, def2191.h, be included also. This header details the addresses for all of the I/O space registers. It should be noted that the addressing scheme utilized in this header assumes that the user has already set the IO Page (IOPG) register appropriately, which is one of the system registers detailed in the enumerated type in sysreg.h (sysreg_IOPG). The IO Pages are also given convenient names in def2191.h.
For example, if the user wanted to configure their ADSP-2191 EZ-KIT to have LEDs 8-11 as outputs, this routine would do the trick:
#include <sysreg.h> #include <def2191.h> main( ) {
sysreg_write (sysreg_IOPG, General_Purpose_IO);
io_space_write (DIRS, 0x000F); }
LEDs 8-11 map to the Programmable Flag Pins 0-3. Therefore, we want to configure PF0-3 to be outputs. This information is contained in the DIRS register, where a 1 means that the PFx pin is an output. The first thing we need to do is to make sure that we are on the correct IO Page for accessing the DIRS register. Because IOPG is a system register, this is accomplished using the sysreg_write intrinsic with the correct arguments. The first argument is the register to be written to,
sysreg_IOPG (as defined in the enumeration in sysreg.h). The second argument is the value to
be written to the IOPG register,
General_Purpose_IO, which is #defined in
def2191.h to be 0x06 (the page offset required to
access the GPIO register set).
Now that the IOPG register is set appropriately to access the GPIO registers, we have access to the DIRS register. The second line of code uses the io_space_write intrinsic because DIRS is an IO space register. Here, the arguments are the address to be written to, DIRS, which is physical I/O address on IO page 6 of the DIRS register) and the value to be written to that address, 0x000F, where bits 0-3 are set to 1 to enable the corresponding PF pins 0-3 to be outputs.
the same fashion, as you will see in the attached code. First, you must set the IOPG register using the sysreg_write intrinsic to have the offset for the Timer_Page. Then you’ll have access to the timer register addresses and must use the io_space_write intrinsic to configure the associated registers as appropriate (see lines 27­34 of the attached source).
#defined in def2191.h to be 0x001 (the
Accessing the Timer0 registers is done in

Interrupt Handling In C

The interrupt handling in C is unchanged from the ADSP-218x family tools from a coding perspective. Users still utilize the header-defined interrupt(signal, subroutine) module to take care of everything. First and foremost, this function associates a specific ISR module to be run for any given signal that could be received during run-time. The list of possible signals is detailed in the signal.h header file. This function also sets the correct bit in IMASK to enable servicing for that interrupt. In addition to this interrupt­registering scheme, the user will have to globally enable interrupts by using the intrinsic function enable_interrupts().
Prior to version 6.1.1 of the ADSP-219x
L
Compiler, global enabling of interrupts was automatically performed by the interrupt(signal, subroutine) module. From version 6.1.1 on, explicit use of the
Using C To Implement Interrupt-Driven Systems On ADSP-219x DSPs (EE-188) Page 2 of 5
Loading...
+ 3 hidden pages