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

📄 btc_asmdemo.asm

📁 基于visual dsp++开发环境
💻 ASM
字号:
/////////////////////////////////////////////////////////////////////////////
//
// Example assembly program using Background Telemetry Channel (BTC)
// Analog Devices 2003
//
// This program defines several BTCs to allow transfer of data over the BTC
// interface while the DSP is running.  Use the BTC Memory window in the
// debugger to view each channels data.  The defined channels are described
// below:
// 
// Timer Interrupt Counter:  This channel is defined to be 1-word (4-bytes)
//		   				     in length and simply counts the number of timer
//							 interrupts that have occured.
//
// PF4 Counter:	 This channel is defined to be 1-word (4-bytes) in length and
//			     simply counts the number of times the PF4 pushbutton is pressed
//				 on the BF535 Ez-Kit.
//
// PF5 Counter:  This channel is defined to be 1-word (4-bytes) in length and
//			     simply counts the number of times the PF5 pushbutton is pressed
//				 on the BF535 Ez-Kit.
//
// 256 word channel (PF6):  This channel is defined to be 256-words (1024-bytes) in length and
//			     			simply counts the number of times the PF6 pushbutton is pressed
//				 			on the Bf535 Ez-Kit.  Each byte in the channel is updated with the count.
//
// 256 word channel (PF7):  This channel is defined to be 256-words (1024-bytes) in length and
//			     			simply counts the number of times the PF7 pushbutton is pressed
//				 			on the BF535 Ez-Kit.  Each byte in the channel is updated with the count.
//
// 256 byte channel:  This channel is defined to be 256 bytes in length.  The first word of the
//					  channel is used to count the number of timer interrupts that have occured.
//
// 4k byte channel:   This channel is defined to be 4-kbytes in length.  The first word of the
//					  channel is used to count the number of timer interrupts that have occured.
//
/////////////////////////////////////////////////////////////////////////////

#include "defbf535.h"
#include "defblackfin.h"
#include "btc.h"

/////////////////////////
// variable definitions
/////////////////////////
.section data1;
.var timerCounter;			// counts the number of timer interrupts that have fired
.var pf4Counter;			// counts the number of times the PF4 pushbutton on the ez-kit was pressed
.var pf5Counter;			// counts the number of times the PF5 pushbutton on the ez-kit was pressed
.byte pf6Array[256];		// a 256 byte array
.byte pf7Array[256];		// a 256 byte array
.byte array1[0x100];		// a 256 byte array
.byte array2[0x1000];		// a 4k byte array


////////////////////
// BTC Definitions
////////////////////
BTC_MAP_BEGIN
//             Channel Name,             Starting Address, Length
BTC_MAP_ENTRY('Timer Interrupt Counter', timerCounter,     0x00004)
BTC_MAP_ENTRY('PF4 Counter', 			 pf4Counter,       0x00004)
BTC_MAP_ENTRY('PF5 Counter', 			 pf5Counter,       0x00004)
BTC_MAP_ENTRY('256 byte channel (PF6)',  pf6Array,         0x00100)
BTC_MAP_ENTRY('256 byte channel (PF7)',  pf7Array,         0x00100)
BTC_MAP_ENTRY('256 byte channel', 		 array1,           0x00100)
BTC_MAP_ENTRY('4k byte channel', 		 array2,           0x01000)
BTC_MAP_END


////////////////////
// main program
////////////////////
.section program;
.extern ldf_stack_end;
.global _main;
_main:
		// initialize the stack pointer
		sp.h = ldf_stack_end;
		sp.l = ldf_stack_end;
				
		// setup the EVT
		[--sp] = rets;
		call initVectorRegs;
		rets = [sp++];
		// setup the Core Timer
		[--sp] = rets;
		call initCoreTimer;
		rets = [sp++];
		// setup the Programmable Flags
		[--sp] = rets;
		call initProgFlags;
		rets = [sp++];
		
		// initialize the BTC
		[--sp] = rets;
		call _btc_init;
		rets = [sp++];
				
		// R2 is used to hold the value to be displayed on the LEDs of the ez-kit
		r2 = 0;
		
		// latch interrupt15 so we can stay in supervisor mode once we return from
		// the reset interrupt
		raise 15;
		
		// unmask the timer interrupt (EVT6), PF interrupt A (EVT12), and EVT15 in IMASK
		i0.h = IMASK >> 16;
		i0.l = IMASK & 0xffff;
		m0 = 0;
		r0.h = 0;
		r0.l = EVT_IVTMR | EVT_IVG12 | EVT_IVG15;
		[i0] = r0;
		
		// enable the timer
		i0.h = TCNTL >> 16;
		i0.l = TCNTL & 0xffff;
		m0 = 0;
		r0 = TMPWR | TMREN | TAUTORLD;
		[i0] = r0;

		// clear the pending reset interrupt (return to User mode) and
		// set all other return regs to a known spot (except RETE)
		nop;
		r0.h = MAIN_WAIT_LOOP;
		r0.l = MAIN_WAIT_LOOP;
		reti = r0;
		rets = r0;
		retn = r0;
		retx = r0;
		nop;
		r0 = 0;
		rti;	// return from supervisor mode to user mode!!
		nop;	// never executed
		nop;	// never executed

		// because we've latched int15 we'll never actually get into this 
		// loop, we should branch directly to the EVT15_LOOP and stay there.
MAIN_WAIT_LOOP:
		nop;
		nop;
		jump MAIN_WAIT_LOOP;

EVT15_LOOP:
		nop;
		nop;
		nop;
		[--sp] = rets;
		call _btc_poll;			// check for incoming BTC commands
		rets = [sp++];
		nop;			
		nop;
		nop;
		jump EVT15_LOOP;
_main.end:

/////////////////////////////////////////////////////////////////////////
//  initVectorRegs
//
//  initialize the vector (EVT) registers
// 
initVectorRegs:
		// access to the EVT0 (EMU), EVT1 (RST), and EVT4 (Reserved) cause exceptions so
		// don't initialize those entries in the EVT.

		// init the vector table
		//i0.h = EVT0 >> 16;
		//i0.l = EVT0 & 0xffff;
		//m0 = 4;
		//r0.h = evt0;
		//r0.l = evt0;
		//[i0++m0] = r0;
		//r0.h = evt1;
		//r0.l = evt1;
		//[i0++m0] = r0;

		i0.h = EVT2 >> 16;
		i0.l = EVT2 & 0xffff;
		m0 = 4;
		r0.h = evt2;
		r0.l = evt2;
		[i0++m0] = r0;
		r0.h = evt3;
		r0.l = evt3;
		[i0++m0] = r0;

		//r0.h = evt4;
		//r0.l = evt4;
		//[i0++m0] = r0;

		i0.h = EVT5 >> 16;
		i0.l = EVT5 & 0xffff;
		m0 = 4;
		r0.h = evt5;
		r0.l = evt5;
		[i0++m0] = r0;
		r0.h = evt6;
		r0.l = evt6;
		[i0++m0] = r0;
		r0.h = evt7;
		r0.l = evt7;
		[i0++m0] = r0;
		r0.h = evt8;
		r0.l = evt8;
		[i0++m0] = r0;
		r0.h = evt9;
		r0.l = evt9;
		[i0++m0] = r0;
		r0.h = evt10;
		r0.l = evt10;
		[i0++m0] = r0;
		r0.h = evt11;
		r0.l = evt11;
		[i0++m0] = r0;
		r0.h = evt12;
		r0.l = evt12;
		[i0++m0] = r0;
		r0.h = evt13;
		r0.l = evt13;
		[i0++m0] = r0;
		r0.h = evt14;
		r0.l = evt14;
		[i0++m0] = r0;
		r0.h = evt15;
		r0.l = evt15;
		[i0++m0] = r0;
		rts;


/////////////////////////////////////////////////////////////////////////
//  Interrupt Service Routines
//
//  functions to handle each interrupt
// 
evt0:	// Emulation (EMU)
		nop;
		nop;
		nop;
		rti;
evt1:	// Reset (RST)
		nop;
		nop;
		nop;
		rti;
evt2:	// Non-Maskable Interrupt (NMI)
		nop;
		nop;
		nop;
		rtn;
evt3:	// Exception (EVX)
		nop;
		nop;
		nop;
		rtx;
evt4:	// Reserved
		nop;
		nop;
		nop;
		rti;
evt5:	// Hardware Error (IVHW)
		nop;
		nop;
		nop;
		rti;
evt6:   // Timer (IVTMR)
		[--sp] = p2;
		[--sp] = p1;
		[--sp] = r0;
		
		// count the number of timer interrupts
		p1.h = timerCounter;
		p1.l = timerCounter;
		r0 = [p1];
		r0 += 1;
		[p1] = r0;
		
		// update the first location of array1
		p1.h = array1;
		p1.l = array1;
		[p1] = r0;
		
		// update the first location of array2
		p1.h = array2;
		p1.l = array2;
		[p1] = r0;
		
		// p1 points to PF Set register (turns LEDs on)
		p1.h = FIO_FLAG_S >> 16;
		p1.l = FIO_FLAG_S & 0xffff;
		// p2 points to PF Clear register (turns LEDs off)
		p2.h = FIO_FLAG_C >> 16;
		p2.l = FIO_FLAG_C & 0xffff;
	
		nop;
		w[p2] = r2;		// turn LEDs off
		bittgl(r2, 3);
		w[p1] = r2;		// turn LEDs on

		r0 = [sp++];
		p1 = [sp++];
		p2 = [sp++];
		rti;
evt7:	// Interrupt 7 (IVG7)
		nop;
		nop;
		nop;
		rti;
evt8:	// Interrupt 8 (IVG8)
		nop;
		nop;
		nop;
		rti;
evt9:	// Interrupt 9 (IVG9)
		nop;
		nop;
		nop;
		rti;
evt10:	// Interrupt 10 (IVG10)
		nop;
		nop;
		nop;
		rti;
evt11:	// Interrupt 11 (IVG11)
		nop;
		nop;
		nop;
		rti;
evt12:	// Interrupt 12 (IVG12)
		[--sp] = p2;
		[--sp] = p1;
		[--sp] = r0;
		[--sp] = lc0;
		[--sp] = lt0;
		[--sp] = lb0;
		[--sp] = astat;
		
		// p1 points to PF Set register (turns LEDs on)
		p1.h = FIO_FLAG_S >> 16;
		p1.l = FIO_FLAG_S & 0xffff;

		// check to see if the PF4 pushbutton was pressed
checkPF4:		
		r0 = w[p1];
		cc = bittst(r0, 4);
		if !cc jump checkPF5;
		
		// count the number of times PF4 was pressed
		p1.h = pf4Counter;
		p1.l = pf4Counter;
		r0 = [p1];
		r0 += 1;
		[p1] = r0;		
		jump neitherPFpressed;
		
		// check to see if the PF5 pushbutton was pressed
checkPF5:
		cc = bittst(r0, 5);
		if !cc jump checkPF6;		
		
		// count the number of times PF5 was pressed
		p1.h = pf5Counter;
		p1.l = pf5Counter;
		r0 = [p1];
		r0 += 1;
		[p1] = r0;
		jump neitherPFpressed;

		// check to see if the PF6 pushbutton was pressed
checkPF6:
		cc = bittst(r0, 6);
		if !cc jump checkPF7;		
		
		// count the number of times PF6 was pressed
		p1.h = pf6Array;
		p1.l = pf6Array;
		r0 = LENGTH(pf6Array);
		lc0 = r0;
		
		loop INC_CHAN3 lc0;
		loop_begin INC_CHAN3;
			r0 = b[p1];
			r0 += 1;
			b[p1++] = r0;
		loop_end INC_CHAN3;
		jump neitherPFpressed;				

		// check to see if the PF7 pushbutton was pressed
checkPF7:
		cc = bittst(r0, 7);
		if !cc jump neitherPFpressed;		
		
		// count the number of times PF7 was pressed
		p1.h = pf7Array;
		p1.l = pf7Array;
		r0 = LENGTH(pf7Array);
		lc0 = r0;
		
		loop INC_CHAN4 lc0;
		loop_begin INC_CHAN4;
			r0 = b[p1];
			r0 += 1;
			b[p1++] = r0;
		loop_end INC_CHAN4;
		
neitherPFpressed:		
		// p1 points to PF Set register (turns LEDs on)
		p1.h = FIO_FLAG_S >> 16;
		p1.l = FIO_FLAG_S & 0xffff;
		// p2 points to PF Clear register (turns LEDs off)
		p2.h = FIO_FLAG_C >> 16;
		p2.l = FIO_FLAG_C & 0xffff;

		nop;
		[--sp] = r2;		// save R2 on stack
		r2.h = 0;
		r2.l = 0x00f0;		// clear the state of the input pins!!
		w[p2] = r2;
		r2 = [sp++];		// restore R2

		w[p2] = r2;			// turn LEDs off		
		bittgl(r2, 0);		// toggle LED state
		w[p1] = r2;			// turn LEDs on

		astat = [sp++];
		lb0 = [sp++];
		lt0 = [sp++];
		lc0 = [sp++];
		r0  = [sp++];
		p1  = [sp++];
		p2  = [sp++];
		rti;

evt13:	// Interrupt 13 (IVG13)
		nop;
		nop;
		nop;
		rti;
evt14:	// Interrupt 14 (IVG14)
		nop;
		nop;
		nop;
		rti;
evt15:	// Interrupt 15 (IVG15)
		[--sp] = reti;			// this allows nesting of interrupts
		nop;
		p0.h = EVT15_LOOP;
		p0.l = EVT15_LOOP;
		jump(p0);
		// this code will never be reached (intentionally)
		nop;
		nop;
		reti = [sp++];			// restore return address
		rti;

/////////////////////////////////////////////////////////////////////////
//  initCoreTimer
//
//  function to initialize the Core Timer registers
// 
initCoreTimer:
		i0.h = TCNTL >> 16;
		i0.l = TCNTL & 0xffff;
		m0 = 4;
		r0.h = 0;
		r0.l = TMPWR | TAUTORLD;	// set TMPWR and TAUTORLD, but don't enable the timer yet
		[i0++m0] = r0;
		// setup the timer period register
		r0.h = 0x0001;
		r0.l = 0x0000;
		[i0++m0] = r0;
		// setup the timer scale register
		r0.h = 0x0000;
		r0.l = 0x0080;
		r3 = 0;
		r4 = r0;
		[i0++m0] = r0;
		// setup the timer count register
		r0.h = 0x0001;
		r0.l = 0x0000;
		[i0++m0] = r0;
		rts;
/////////////////////////////////////////////////////////////////////////
//  initProgFlags
//
//  function to initialize the Programmable Flags registers
// 
initProgFlags:
		// p0 points to PF Config register
		p0.h = FIO_DIR >> 16;
		p0.l = FIO_DIR & 0xffff;

		// set PF0 - PF3 to outputs, PF4 - PF15 left as inputs
		// PF4 - PF7 pushbuttons will be capture as interrupts
		r0 = 0xf;
			
		// set all PF's to outputs
		w[p0] = r0;

		// p1 points to PF Set register (turns LEDs on)
		p1.h = FIO_FLAG_S >> 16;
		p1.l = FIO_FLAG_S & 0xffff;
		// p2 points to PF Clear register (turns LEDs off)
		p2.h = FIO_FLAG_C >> 16;
		p2.l = FIO_FLAG_C & 0xffff;

		// turn all LEDs off
		r0 = -1;
		w[p2] = r0;

		// p3 points to PF Interrupt A Mask Set register
		p3.h = FIO_MASKA_S >> 16;
		p3.l = FIO_MASKA_S & 0xffff;
		// enable PF4 - PF7 interrupts
		r0.h = 0;
		r0.l = 0x00f0;
		w[p3] = r0;
		
		// p3 points to PF Polarity register
		p3.h = FIO_POLAR >> 16;
		p3.l = FIO_POLAR & 0xffff;
		// polarity is Active Hi (0) or Active Low (1)
		r0.h = 0;
		r0.l = 0x0000;
		w[p3] = r0;
		
		// p3 points to PF Interrupt Sensitivity register
		p3.h = FIO_EDGE >> 16;
		p3.l = FIO_EDGE & 0xffff;
		// setup PF4 - PF7 for edge triggered interrupts (1)
		r0.h = 0;
		r0.l = 0x00f0;
		w[p3] = r0;
		
		//Check revision of silicon 
				
		// p0 points to CHIPID register
		p0.h = 0xffc0;
		p0.l = 0x48c0;
		r2 = [p0];
		r1.h = 0xf000;
		r1.l = 0x0000;
		// if the CHIPID is non-zero, a "1" in SIC_IMASK will enable system interrupts
		r1 = r1 & r2;
		cc = az;
		if !cc jump newSilicon;

		// any rev silicon of 1.0 or later will have system interrupts enabled by writing
		// a 1 to the appropriate bit in SIC_IMASK.  Revisions prior to 1.0 are enabled
		// by writing a 0.

oldSilicon:
		//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;
		rts;

newSilicon:
		//Unmask the PF Interrupt A in System Interrupt Mask Register
		p3.l = SIC_IMASK & 0xffff;
		p3.h = SIC_IMASK >> 16;
		r6 = [p3];
		bitset(r6,17);   
		[ p3 ] = r6;
		rts;


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -