⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pwr_mgmt.asm

📁 This directory contains example ADSPBF535 code, written in assembly, that changes the frequency and
💻 ASM
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************************************************

(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 + -