📄 pwr_mgmt.asm
字号:
/*****************************************************************************************************************
(C) Copyright 2001 - Analog Devices, Inc. All rights reserved.
File Name: pwr_mgmt.asm
Date Modified: 12/20/01 CL Rev 0.1
Purpose: ADSP-BF535 EZ-Kit Lite Power Management example
Developed using the ADSP-BF535 EZ-KIT Lite Evaluation Platform
This program contains routines to initialize the
state of the ADSP-BF535 event controller.
This routine, written in assembly, changes the frequency and voltage using the push
button switches on the board. By pushing switch 4, the frequency and voltage become 300MHz and
1.5 volts. By pushing switch 5, the frequency and voltage become 160MHz and
1.2 volts. By pushing switch 6, the frequency and voltage become 100MHz and
1.0 volts, respectively.
LED4 is on when the part is running at 300MHz
LED1 is on when the part is running at 160MHz
LED2 is on when the part is running at 100MHz
The CLKOUT pin on the P3 connector shows the system clock at these frequencies (120MHz,
66MHz and 40MHz) with the 2.5 SSEL value
The WD counts have been increased so the frequency changes can be observed on a scope.
Each transition puts the part in bypass.
When the part is in bypass, the core clock runs at 0.5*CLKIN, or 10MHz. The system clock (CLKOUT)
will be at 10/2.5 or 4MHz during this time.
This code could be much shorter but it is expanded out to clearly show the steps required
to change the voltage and frequency.
The EZ-Kit power management example is meant to provide a prototype capability
to allow a user to change the frequency and or voltage on the fly. This ADI
chip set is connected via 3 FIO pins. An ADI companion chip will be available which
can be interfaced to with a single timer pin.
Note: See chapter 8 of the HW Refrence Manual for a full description of the
ADSP-BF535 Power Management capabilities.
************************************************************************************************/
#include "defBF535.h"
.section l2_bank0;
SETUP:
// Setup Event Vectors and Handlers
p0.l = EVT0 & 0xffff;
p0.h = EVT0 >> 16;
r0 = _EHANDLER (Z); // Emulation Handler (Int0)
r0.h = _EHANDLER;
[ P0 ++ ] = R0;
R0 = _RHANDLER (Z);
R0.H = _RHANDLER; // Reset Handler (Int1)
[ P0 ++ ] = R0;
R0 = _NHANDLER (Z);
R0.H = _NHANDLER; // NMI Handler (Int2)
[ P0 ++ ] = R0;
R0.L = _XHANDLER;
R0.H = _XHANDLER; // Exception Handler (Int3)
[ P0 ++ ] = R0;
[ P0 ++ ] = R0; // IVT4 isn't used
R0 = _HWHANDLER (Z);
R0.H = _HWHANDLER; // HW Error Handler (Int5)
[ P0 ++ ] = R0;
R0 = _THANDLER (Z);
R0.H = _THANDLER; // Timer Handler (Int6)
[ P0 ++ ] = R0;
R0 = _RTCHANDLER (Z);
R0.H = _RTCHANDLER; // IVG7 Handler
[ P0 ++ ] = R0;
R0 = _I8HANDLER (Z);
R0.H = _I8HANDLER; // IVG8 Handler
[ P0 ++ ] = R0;
R0 = _I9HANDLER (Z);
R0.H = _I9HANDLER; // IVG9 Handler
[ P0 ++ ] = R0;
R0 = _I10HANDLER (Z);
R0.H = _I10HANDLER;// IVG10 Handler
[ P0 ++ ] = R0;
R0 = _I11HANDLER (Z);
R0.H = _I11HANDLER;// IVG11 Handler
[ P0 ++ ] = R0;
R0 = _I12HANDLER (Z);
R0.H = _I12HANDLER;// IVG12 Handler
[ P0 ++ ] = R0;
R0 = _I13HANDLER (Z);
R0.H = _I13HANDLER;// IVG13 Handler
[ P0 ++ ] = R0;
R0 = _I14HANDLER (Z);
R0.H = _I14HANDLER;// IVG14 Handler
[ P0 ++ ] = R0;
R0 = _I15HANDLER (Z);
R0.H = _I15HANDLER;// IVG15 Handler
[ P0 ++ ] = R0;
sp.h = 0xFFb0; //Set up supervisor stack
sp.l = 0x0f00;
p0.l = _main;
p0.h = _main;
reti = p0;
// Enable Interrupt 15
p0.l = EVT15 & 0xffff;
p0.h = EVT15 >> 16;
r0.l = ISR15;
r0.h = ISR15;
[p0++] = r0;
r0 = 0x8000(z);
sti r0;
raise 15;
rti;
ISR15:
[--SP] = RETI;
p0.l = _main;
p0.h = _main;
JUMP (P0);
ISR15.END: JUMP ISR15;
_main:
P0.L = IMASK & 0xffff;
P0.H = IMASK >> 16;
R0 = [P0]; // Change this to unmask FIO interrupt
BITSET(R0,12); // Unmask IVG12--mapped to PF Interrupts A/B
W[ P0 ] = R0; // write to IMASK register
r7.l = 0x0000; // Set watchdog to wakeup core from IDLE;SSYNC;
r7.h = 0x0010;
p0.l = SIC_IWR & 0xffff;
p0.h = SIC_IWR >> 16;
[p0] = r7;
ssync;
r7.l = 0x00a1; //The PLL lock bit will be set when this counter expires
r7.h = 0x0000;
p0.l = LOCKCNT & 0xffff; // The counter begins counting when the DSP enters IDLE mode.
p0.h = LOCKCNT >> 16;
W[p0] = r7;
ssync;
//Check revision of silicon
P0.L = CHIPID & 0xffff;
P0.H = CHIPID >> 16;
R0 = [P0];
R1.H = 0xf000;
R1.L = 0x0000;
R1 = R1 & R0;
CC = AZ; // If the CHIPID is non-zero, a "1" in SIC_IMASK will enable system interrupts
if !CC jump new;
old:
//Unmask the PF Interrupt A in System Interrupt Mask Register
p3.l = SIC_IMASK & 0xffff;
p3.h = SIC_IMASK >> 16;
R6 = [p3];
BITCLR(R6,17);
[ P3 ] = R6;
jump set_pointer;
new:
p3.l = SIC_IMASK & 0xffff;
p3.h = SIC_IMASK >> 16;
R6 = [p3];
BITSET(R6,17); // any rev of 1.0 or later will have system interrupts enabled by writing a 1 to the appropriate
[ P3 ] = R6; // bit
//Setup pointer registers
set_pointer:
P0.L = FIO_DIR & 0xffff;
P0.H = FIO_DIR >> 16;
P1.L = FIO_FLAG_S & 0xffff;
P1.H = FIO_FLAG_S >> 16;
P2.L = FIO_FLAG_C & 0xffff;
P2.H = FIO_FLAG_C >> 16;
P3.L = FIO_MASKA_S & 0xffff;
P3.H = FIO_MASKA_S >> 16;
P4.L = FIO_POLAR & 0xffff;
P4.H = FIO_POLAR >> 16;
P5.L = FIO_EDGE & 0xffff;
P5.H = FIO_EDGE >> 16;
/* PF0-3 are mapped to LEDs. */
/* Set as outputs to light LEDs indicating which push button routine current program flow is in. */
R0.L = 0x000F;
W[P0] = R0.L;
/* Clear LEDs (PF0-3) as well as state of pushbutton pins (PF4-7) */
R2.L = 0x00FF;
W[P2] = R2.L;
/* Unmask interrupts for pushbuttons PF4-6 (PF7 is not used.) */
/* Only Interrupt A is unmasked and enabled. */
R3.L = 0x0070;
W[P3] = R3.L;
/* Enable rising edge detection for push button activity. */
R5.L = 0x0000;
R4.L = 0x0000;
W[P5] = R5.L; /*set PF4-6 to be edge sensitive*/
W[P4] = R4.L; /*set all PFs to be rising edge sensitive*/
ssync;
wait_here: jump wait_here;
// Handlers for Events
_EHANDLER: // Emulation Handler 0
RTE;
_RHANDLER: // Reset Handler 1
RTI;
_NHANDLER: // NMI Handler 2
RTN;
_XHANDLER: // Exception Handler 3
RTX;
_HWHANDLER: // HW Error Handler 5
RTI;
_THANDLER: // Timer Handler 6
RTI;
_RTCHANDLER: // IVG 7 Handler (RTC)
RTI;
_I8HANDLER: // IVG 8 Handler
RTI;
_I9HANDLER: // IVG 9 Handler
RTI;
_I10HANDLER: // IVG 10 Handler
RTI;
_I11HANDLER: // IVG 11 Handler
RTI;
_I12HANDLER: // IVG 12 Handler
// This ISR is used to handle the FIO interrupt
// generated when a button is pushed
r4=W[p1]; // Check value of flag pins to see which button was pushed
cc=bittst(r4,4);
if cc jump three_hundred;
cc=bittst(r4,5);
if cc jump one_fifty;
cc=bittst(r4,6);
if cc jump one_hundred;
rti;
/***change voltage to 1.5 volts and frequency to 300MHz
***must change voltage before changing frequency******
***set PF14 to 1, PF13 to 1, and PF12 to 0 ***********/
three_hundred:
p0.l = FIO_DIR & 0xffff; // Program the power management chip
p0.h = FIO_DIR >> 16;
r7=W[p0];
bitset(r7, 12);
bitset(r7, 13);
bitset(r7, 14);
W[p0]=r7;
r5=0x0000(z);
bitset(r5,14);
bitset(r5,13); // using 3 FIO pins - 110 = 1.5V
W[p1]=r5; // FIO set register
ssync;
r5=0x0000(z);
bitset(r5,12); // FIO clear register
W[p2]=r5;
// Voltage is now at 1.5V
/***************change frequency*******/
// When we change the value of MSEL, we have the put the PLL into bypass mode
r7.l = 0xfff1; // Set watchdog count value to allow enough time for transition and PLL lock
r7.h = 0x0000;
p0.l = WDOGCNT & 0xffff;
p0.h = WDOGCNT >> 16;
[p0] = r7;
ssync;
p0.l = PLLCTL & 0xffff;
p0.h = PLLCTL >> 16;
r7 = [p0];
bitset(r7,8); // Set bypass mode on
[p0] = r7; // set the PLLCTL to: PLL bypassed
ssync;
r7.l = 0x0000; // Reload WD count register
r7.h = 0x0000;
p0.l = WDOGSTAT & 0xffff;
p0.h = WDOGSTAT >> 16;
[p0] = r7;
ssync;
r7.l = 0x0004; // Enable watchdog GP Interrupt
p0.l = WDOGCTL & 0xffff;
p0.h = WDOGCTL >> 16;
W[p0] = r7;
ssync;
cli r7;
idle;
ssync; // Enter IDLE mode to allow PLL to enter bypass state
sti r7; // First instruction executed when WD interrupt is generated
// The WD interrupt is not enabled. The wakeup event from the WD is what
// actually brings the DSP out of IDLE
r7.l = 0x8006; // Clear WD flag and disable WD events
p0.l = WDOGCTL & 0xffff;
p0.h = WDOGCTL >> 16;
W[p0] = r7;
ssync;
r7.l = 0x1F00; // set the PLLCTL to: PLL bypassed, MSEL: 15x, SSEL: CCLK/2.5
r7.h = 0x0001;
p0.l = PLLCTL & 0xffff;
p0.h = PLLCTL >> 16;
[p0] = r7;
ssync;
p0.l = PLLCTL & 0xffff;
p0.h = PLLCTL >> 16;
r7 = [p0]; // Read the value in PLLCTL
bitclr(r7,8); // Set bypass mode off
[p0] = r7; // set the PLLCTL to: PLL not bypassed
ssync;
r7.l = 0x0000; // Reload WD counter
r7.h = 0x0000;
p0.l = WDOGSTAT & 0xffff;
p0.h = WDOGSTAT >> 16;
[p0] = r7;
ssync;
r7.l = 0x0004;
p0.l = WDOGCTL & 0xffff;
p0.h = WDOGCTL >> 16;
W[p0] = r7;
ssync;
nop;
cli r7;
idle; // Exit PLL bypass mode
ssync;
sti r7;
ssync;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -