Using C To Create Interrupt Driven Systems On Blackfin Processors
Using C To Create Interrupt Driven Systems On Blackfin Processors
Technical Notes on using Analog Devices' DSP components and development tools
a 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
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 technical accuracy and topicality of the content provided in Analog Devices Engineer-to-Engineer Notes.
a
consumes 4 bytes of memory and whose sole and SIC_IAR2. Refer to Chapter 4 (Program
purpose is to hold the address of IMASK so that Sequencer) of the appropriate Hardware
the user can indirectly write a 1 to the register by Reference Manual (either ADSP-BF535 or
accessing it through its mapped address. This ADSP-BF533) for more information regarding
convention wastes 4 bytes of memory for every interrupt priority assignments.
register accessed in this fashion! Several peripheral sources can share the same
An alternate method of manipulating the IMASK SIC interrupt assignment. Those sources with
register without consuming memory for the common interrupt assignments share the same
pointer is to force a casted pointer in the code to General-purpose interrupt (IVGx). Table 4-8 of
modify the address directly: the Hardware Reference Manual depicts the
*(volatile long *)IMASK |= 0x1; IVG-Select Definitions, which is where the
values programmed into the specific fields of the
In the Blackfin C-defines header files, all of the
SIC_IARx registers are translated into an IVG
memory-mapped registers have already been set
priority. Use the IVG priority detailed here to
up for access in C in a series of #define
determine which IMASK bit to set in the Core
statements, like this:
Event Controller (CEC) to enable interrupt
#define pIMASK ((volatile long *)IMASK)
handling for this group of peripherals.
This method allows the user to use the same C In addition to having a group of interrupt sources
syntax in their code, *pIMASK |= 0x1, to modify enabled in the CEC, handling for each sources
the registers contents without dedicating individual interrupt is enabled separately on the
memory for the pointer. Instead, the compilers SIC level in the SIC_IMASK register. For
pre-processor substitutes the casted pointer example, one could set each peripherals IVG
syntax for what appears to be pointer-modifying priority to the same level, thus making one group
code. So, if one knows the name of the register, of 24 potential interrupt sources. If only one of
one can easily access that register using standard those peripheral interrupts is enabled in
C code for pointer modification: SIC_IMASK, then the IVG effectively describes
*pREGISTER_NAME = VALUE; that single interrupt source because that single
These cdef header files were created for each source is the only source enabled at the SIC level
individual processor based upon the widths of to be recognized by the core as a peripheral
the registers being represented (i.e., a 16-bit interrupt source.
register uses the short int type, which the An abridged overview of how to set peripheral
Blackfin compiler treats as 16-bit data, whereas a interrupts up correctly goes like this:
32-bit register is represented as a long int or int
type). 1. Enable peripherals individual interrupt in
SIC_IMASK register.
Blackfin Interrupts (Hardware) 2. Program the interrupt priority levels into the
SIC_IARx registers. This step is optional.
The Blackfin family of processors has an
intricate interrupt system that includes core 3. Use the values in the SIC_IARx registers
interrupts, enabled in the IMASK register, and with Table 4-8 of the Hardware Reference
peripheral interrupts, which are configured in the Manual to determine which interrupt group
System Interrupt Controller (SIC). These (IVGx) the peripheral of interest is assigned
system-level peripheral interrupts are optionally to.
user-configurable in a set of System Interrupt 4. Set the appropriate IVGx bit in the IMASK
Assignment Registers: SIC_IAR0, SIC_IAR1, register.
According to the reset values of the SIC_IARx assigns the name of the ISR function, ISR_Name,
registers, the default value in the Timer0 field of to the core event represented by IVGx by writing
SIC_IAR1 is 0x4. Table 4-8 of the Hardware the ISR functions address to the corresponding
Reference Manual tells us that the value 0x4 EVTx register. The function prototype and
maps to IVG11, therefore, IVG11 is the default enumeration of interrupt kinds can be found in
core interrupt channel for the Timer0 interrupt. the sys\exception.h header file.
So, the last step in setting up peripheral Checking the sys\exception.h header file, it can
interrupts in the hardware is to enable IVG11 in be seen that the signal number for IVG11 is
the CECs IMASK register. ik_ivg11. Therefore, use of this macro in this
example is:
mixed.c
/*****************************************************************************
* Uncomment the following pre-processor directive if building code for the *
* ADSP-BF533 EZ-KIT. ADSP-BF535-EZKIT users do not need to modify this. *
* Including BF533_PROJECT changes the legacy ADSP-BF535 code to use the *
* BF533 header, redefine the MAX value on the LEDs, use the BF533 timer *
* registers, and configure the flash to use the LEDs to output patterns *
*****************************************************************************/
#ifdef BF533_PROJECT
#include <cdefBF533.h> // BF533 Register Pointer Definitions
#else
#include <cdefBF535.h> // BF535 Register Pointer Definitions
#endif
// Prototypes
#ifdef BF533_PROJECT
void Init_EBIU_Flash(void); // Flash Init Code Needed For BF533-EZKIT
#else
void Init_Flags(void); // Flags Mapped To LEDs For BF535-EZKIT
#endif
void Init_Timer(void);
void Init_Interrupts(void);
// Selects All LEDs, Also Used For ISR Compare For All LEDs Lit
#ifdef BF533_PROJECT
#define MAX_LED_DISPLAY 0x3F // 6 LEDs on BF533, all LIT
#else
#define MAX_LED_DISPLAY 0xF // 4 LEDs on BF535, all LIT
#endif
#ifdef BF533_PROJECT
*pTIMER_STATUS = 1; // Clear Timer0 Interrupt
*pFlashA_PortB_Data = 0x0; // clear LEDs
*pFlashA_PortB_Data = count; // write new LED pattern to Port B
#else
*pTIMER0_STATUS = 1; // Clear Timer0 Interrupt
*pFIO_FLAG_C = 0xF; // clear LEDs
*pFIO_FLAG_S = count; // display new LED pattern
#endif
} // end Timer_ISR
main()
{
#ifdef BF533_PROJECT // If this is for the BF533-EZKIT
Init_EBIU_Flash(); // initialize EBIU for FLASH interface
#else // Otherwise, it is for a BF535-EZKIT
Init_Flags(); // Set All 4 LED PFx Flags To Outputs
#endif
#ifdef BF533_PROJECT
void Init_EBIU_Flash(void)
{
*pEBIU_AMBCTL0 = 0x7bb07bb0;
*pEBIU_AMBCTL1 = 0x7bb07bb0;
*pEBIU_AMGCTL = 0x000f;
void Init_Timer(void)
{
*pTIMER0_CONFIG = 0x0019; // PWM Mode, Period Count,
Interrupt
#ifdef BF533_PROJECT
*pTIMER0_PERIOD = 0x01000000; // Configure Timer Period
*pTIMER0_WIDTH = 0x00800000; // Configure Timer Width
*pTIMER_ENABLE = 0x0001; // Enable Timer
#else
*pTIMER0_PERIOD_HI = 0x0100; // Configure Timer Period
void Init_Interrupts(void)
{
// Enable the SIC interrupt
#ifdef BF533_PROJECT
*pSIC_IMASK = 0x00010000; // Timer0 Default IRQ Is Bit 16 on BF533
#else // if using Rev 1.0 or higher of BF535 silicon, delete the ~ below
*pSIC_IMASK = ~0x00004000; // Timer0 Default IRQ Is Bit 14 on BF535
#endif
// install the handler (also sets IVG11 in IMASK)
register_handler(ik_ivg11, Timer_ISR);
} // end Init_Interrupts
Listing 1: mixed.c
BF535_C_IRQ.c
// Prototypes
void Init_Flags(void); // Flags Mapped To LEDs For BF535-EZKIT
void Init_Timer(void);
void Init_Interrupts(void);
// Selects All LEDs, Also Used For ISR Compare For All LEDs Lit
#define MAX_LED_DISPLAY 0xF // 4 LEDs on BF535, all LIT
EX_INTERRUPT_HANDLER(Timer_ISR)
{
static int count=-1;
main()
{
Init_Flags(); // Set All 4 LED PFx Flags To Outputs
Init_Timer(); // Initialize the Timer0 Registers
Init_Interrupts(); // Configure the Interrupts
void Init_Flags(void)
{
void Init_Timer(void)
{
*pTIMER0_CONFIG = 0x0019; // PWM Mode, Period Count, Interrupt
*pTIMER0_PERIOD_HI = 0x0100; // Configure Timer Period
*pTIMER0_PERIOD_LO = 0x0000;
*pTIMER0_WIDTH_HI = 0x0080; // Configure Timer Width
*pTIMER0_WIDTH_LO = 0x0000;
*pTIMER0_STATUS = 0x0100; // Enable Timer0
} // end Init_Timer
void Init_Interrupts(void)
{
// Enable SIC interrupt, if using Rev 1.0 or higher of ADSP-BF535 silicon,
// delete the ~ below
*pSIC_IMASK = ~0x00004000; // Timer0 Default IRQ Is Bit 14
Listing 2: BF535_C_IRQ.c
BF533_C_IRQ.c
// Prototypes
void Init_EBIU_Flash(void); // Flash Init Code Needed For BF533-EZKIT
void Init_Timer(void);
void Init_Interrupts(void);
// Selects All LEDs, Also Used For ISR Compare For All LEDs Lit
#define MAX_LED_DISPLAY 0x3F // 6 LEDs on BF533, all LIT
EX_INTERRUPT_HANDLER(Timer_ISR)
{
static int count=-1;
} // end Timer_ISR
main()
{
void Init_EBIU_Flash(void)
{
*pEBIU_AMBCTL0 = 0x7bb07bb0;
*pEBIU_AMBCTL1 = 0x7bb07bb0;
*pEBIU_AMGCTL = 0x000f;
void Init_Timer(void)
{
*pTIMER0_CONFIG = 0x0019; // PWM Mode, Period Count, Interrupt
*pTIMER0_PERIOD = 0x01000000; // Configure Timer Period
*pTIMER0_WIDTH = 0x00800000; // Configure Timer Width
*pTIMER_ENABLE = 0x0001; // Enable Timer
} // end Init_Timer
void Init_Interrupts(void)
{
// Enable the SIC interrupt
*pSIC_IMASK = 0x00010000; // Timer0 Default IRQ Is Bit 16
Listing 3: BF533_C_IRQ.c
References
[1] ADSP-BF535 Blackfin Hardware Reference. Revision 1.0, November 2002. Analog Devices, Inc.
[2] ADSP-BF533 Blackfin Hardware Reference. Preliminary Revision, March 2003. Analog Devices, Inc.
[3] VisualDSP++ 3.0 C/C++ Compiler and Library Manual for Blackfin Processors. Second Revision,
April 2002. Analog Devices, Inc.
Document History
Version Description
May 28, 2003 by Joe B. Updated interrupt service routine example code.