📄 btc_asmdemo.asm
字号:
/////////////////////////////////////////////////////////////////////////////
//
// Example assembly program using Background Telemetry Channel (BTC)
// Analog Devices 2006
//
// 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.
//
// PF0 Counter: This channel is defined to be 1-word (4-bytes) in length and
// simply counts the number of times the PF0 pushbutton is pressed
// on the BF538 Ez-Kit. (Must have SW5.1 set to ON for PF0 pushbutton to work)
//
// PF1 Counter: This channel is defined to be 1-word (4-bytes) in length and
// simply counts the number of times the PF1 pushbutton is pressed
// on the BF538 Ez-Kit. (Must have SW5.2 set to ON for PF1 pushbutton to work)
//
// 256 byte channel (PF1): This channel is defined to be 256-bytes in length and
// simply counts the number of times the PF1 pushbutton is pressed
// on the BF538 Ez-Kit. Each byte in the channel is updated with the count.
//
// 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 "defBF538.h"
#include "def_lpblackfin.h"
#include "btc.h"
/////////////////////////
// variable definitions
/////////////////////////
.section data1;
.var timerCounter; // counts the number of timer interrupts that have fired
.var PF0Counter; // counts the number of times the PF0 pushbutton on the ez-kit was pressed
.var PF1Counter; // counts the number of times the PF1 pushbutton on the ez-kit was pressed
.byte PF1Array[256]; // a 256 byte array
.byte array1[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('PF0 Counter', PF0Counter, 0x00004)
BTC_MAP_ENTRY('PF1 Counter', PF1Counter, 0x00004)
BTC_MAP_ENTRY('256 byte channel (PF1)', PF1Array, 0x00100)
BTC_MAP_ENTRY('4k byte channel', array1, 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] = 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;
// toggle the led
p1.h = PORTCIO_TOGGLE >> 16;
p1.l = PORTCIO_TOGGLE & 0xffff;
r0 = PF6;
w[p1] = r0;
r0 = [sp++];
p1 = [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 = PORTFIO_SET >> 16;
p1.l = PORTFIO_SET & 0xffff;
// check to see if the PF0 pushbutton was pressed
checkPF0:
r0 = w[p1] (z);
cc = bittst(r0, 0);
if !cc jump checkPF1;
// count the number of times PF0 was pressed
p1.h = PF0Counter;
p1.l = PF0Counter;
r0 = [p1];
r0 += 1;
[p1] = r0;
jump neitherPFpressed;
// check to see if the PF1 pushbutton was pressed
checkPF1:
cc = bittst(r0, 1);
if !cc jump neitherPFpressed;
// count the number of times PF1 was pressed
p1.h = PF1Counter;
p1.l = PF1Counter;
r0 = [p1];
r0 += 1;
[p1] = r0;
// count the number of times PF1 was pressed
p1.h = PF1Array;
p1.l = PF1Array;
r0 = LENGTH(PF1Array);
lc0 = r0;
loop INC_CHAN4 lc0;
loop_begin INC_CHAN4;
r0 = b[p1] (z);
r0 += 1;
b[p1++] = r0;
loop_end INC_CHAN4;
neitherPFpressed:
// p1 points to PF Toggle register (toggles LEDs)
p1.h = PORTCIO_TOGGLE >> 16;
p1.l = PORTCIO_TOGGLE & 0xffff;
// p2 points to PF Clear register (clears state of PB input)
p2.h = PORTFIO_CLEAR >> 16;
p2.l = PORTFIO_CLEAR & 0xffff;
nop;
[--sp] = r2; // save R2 on stack
r2.h = 0;
r2.l = 0x3; // clear the state of the input pins!!
w[p2] = r2;
r2 = [sp++]; // restore R2
// toggle the LED
r0 = 0;
bittgl(r0, 9);
w[p1] = r0;
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 = 0x0004;
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 = 0x0004;
r0.l = 0x0000;
[i0++m0] = r0;
rts;
/////////////////////////////////////////////////////////////////////////
// initProgFlags
//
// function to initialize the Programmable Flags registers
//
initProgFlags:
// p0 points to PF Config register
p0.h = PORTFIO_DIR >> 16;
p0.l = PORTFIO_DIR & 0xffff;
// set PF0 and PF1 as inputs, all others as outputs
// this assumes that SW13 and SW12 are tied to PF0 and PF1
r0 = 0xFFFC (z);
w[p0] = r0;
// enable input buffers for PF0 and PF1
p0.h = PORTFIO_INEN >> 16;
p0.l = PORTFIO_INEN & 0xffff;
r0 = 0x3 (z);
w[p0] = r0;
// set function enable to GPIO
p1.h = PORTCIO_FER >> 16;
p1.l = PORTCIO_FER & 0xffff;
r0 = 0x3F0;
w[p1] = r0;
// set the direction to output for the LEDs
p1.h = PORTCIO_DIR >> 16;
p1.l = PORTCIO_DIR & 0xffff;
r0 = 0x3F0;
w[p1] = r0;
// p1 points to PF Set register (turns LEDs on)
p1.h = PORTCIO_SET >> 16;
p1.l = PORTCIO_SET & 0xffff;
// p2 points to PF Clear register (turns LEDs off)
p2.h = PORTCIO_CLEAR >> 16;
p2.l = PORTCIO_CLEAR & 0xffff;
// turn all LEDs off
r0 = 0x3F0;
w[p2] = r0;
// p3 points to PF Interrupt A Mask Set register
p3.h = PORTFIO_MASKA_SET >> 16;
p3.l = PORTFIO_MASKA_SET & 0xffff;
// enable PF0 - PF1 interrupts
r0.h = 0;
r0.l = 0x3;
w[p3] = r0;
// p3 points to PF Polarity register
p3.h = PORTFIO_POLAR >> 16;
p3.l = PORTFIO_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 = PORTFIO_EDGE >> 16;
p3.l = PORTFIO_EDGE & 0xffff;
// setup PF0 - PF1 for edge triggered interrupts (1)
r0.h = 0;
r0.l = 0x3;
w[p3] = r0;
//Unmask the PF Interrupt A in System Interrupt Mask Register
p3.l = SIC_IMASK0 & 0xffff;
p3.h = SIC_IMASK0 >> 16;
r6 = [p3];
bitset(r6,19);
[ p3 ] = r6;
rts;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -