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

📄 simd_fir_demo.asm

📁 SIMD_FIRs信号处理
💻 ASM
字号:
/* ///////////////////////////////////////////////////////////////////////////////////
/    FIR_Demo.asm                          21161 EZ-KIT LITE SIMDFIR digital filter  /
/                                                                                    /
/    Receives input from the AD1836 A/D's via the 21161 serial port (SPORT1),        /
/    Filters the data using a Finite Impuse Response Filter, and then stores the     /
/    output for the SPORT1 ISR to transmit the data back to the AD1836 D/A's.        /
/                                                                                    /
/    The digital filter coefficients are in the files "high1.dat" and "low1.dat"     /
/                                                                                    /
/    The samples from the AD1836 are 24-bits and are are converted to                /
/    floating point numbers.  The values are also scaled to the range +/-1.0         /
/    with the integer to float conversion (f0 = float r0 by r1).                     /
/                                                                                    /
/    The digital filtering takes place in the SPORT1 transmit interrupt service      /
/    routine.                                                                        /
/                                                                                    /
/    See the "ADSP-21000 Family Applications Handbook Vol. 1" for more information   /
/    regarding the implementation of digital filters (chapter 4)                     /
/                                                                                    /
/                                                                                    /
/////////////////////////////////////////////////////////////////////////////////// */

/* ADSP-21161 System Register bit definitions */
#include 	"def21161.h"

/* *** C preprocessor declarations (defines, includes, etc.) *** */
#define DOUBLE_FILTER_TAPS 130
#define FILTER_TAPS 65

.section /dm    dm_data;

.VAR	filter_counter = 0;						/* default is low-pass filter */
.ALIGN 2;
.VAR    dline [DOUBLE_FILTER_TAPS];       		/* delay line of input samples */

/*---------------------------------------------------------------------------*/

.section /pm	  pm_data;

/* declare and initialize the interleaved lowpass & highpass filter coefficients*/
.ALIGN 2;
.VAR    coef_lo[DOUBLE_FILTER_TAPS] = "interleaved_coeffsLP_300&600Hz.dat";  
.ALIGN 2;
.VAR	coef_hi[DOUBLE_FILTER_TAPS] = "interleaved_coeffsHP_4&8kHz.dat";

/* "interleaved_coeffsLP_300&600Hz.dat" contains the coefficients for a stereo/interleaved low pass filter and
   "interleaved_coeffsHP_4&8kHz.dat" contains the coefficients for a stereo/interleaved high pass filter */

.section /pm pm_code;

.GLOBAL		init_fir_filter;
.GLOBAL		fir;
.GLOBAL		change_filter_coeffs;

.EXTERN		RX_left_flag;
.EXTERN		Left_Channel_In1;
.EXTERN		Right_Channel_In1;
.EXTERN		Left_Channel_Out0;
.EXTERN		Right_Channel_Out0;
.EXTERN		Left_Channel_Out1;
.EXTERN		Right_Channel_Out1;

init_fir_filter:
	bit set mode1 CBUFEN ;
	nop ;

	/* initialize the DAGS */
	b0 = dline;     	l0 = @dline;    		/* pointer to the samples (delay line) */
	m1 = 2; 

	b9 = coef_lo;		l9 = @coef_lo;   	/* pointer to the highpass filter coefficients  */
	m9 = 2 ;

	i3=dline;	l3=@dline;	r12=r12 xor r12; 	/* clear the delay line */

   	bit set mode1 PEYEN ;
   	lcntr=FILTER_TAPS, do clear until lce;
clear:    dm(i3,2)=f12;
	bit clr mode1 PEYEN ;

   rts;
init_fir_filter.end:

/* //////////////////////////////////////////////////////////////////////////////// *
 *                           FIR filter subroutine                                  *
 * //////////////////////////////////////////////////////////////////////////////// */

fir:
	/* process Left Channel Input */
	r2 = -31;        						/* scale the sample to the range of +/-1.0 */                           
	r0 = DM(Left_Channel_In1);				/* get left input sample */
	r1 = DM(Right_Channel_In1);				/* get right input sample */
	f0 = float r0 by r2 ;					/* and convert to floating point */		
	f1 = float r1 by r2 ;					/* and convert to floating point */

	f8 = f0;								/* in case we are in bypass mode, copy to output */
	f9 = f1;								/* in case we are in bypass mode, copy to output */

	if FLAG2_IN jump exit_filter;

do_filtering:
	dm(i0,m1)=f0 (LW);

	// Enable broadcast mode and also set the PEYEN, disable I9 Broadcast Mode since we have interleaved coeffs
	bit set mode1 PEYEN;
	bit clr mode1 IRPTEN | BDCST9;

	r12=r12 xor r12;     					/* clear f12,put sample in delay line */
	f8=pass f12, f0=dm(i0,m1), f4=pm(i9,m9);/* clear f8,get data & coef */ 

	lcntr=FILTER_TAPS-1, do macloop until lce;
macloop:   f12=f0*f4, f8=f8+f12, f0=dm(i0,m1), f4=pm(i9,m9);

	f12=f0*f4, f8=f8+f12;   				/* perform the last multiply */
	f8=f8+f12;								/* perform the last accumulate */

	bit clr mode1 PEYEN | BDCST9;
	bit set mode1 IRPTEN;
	r9 = s8;

exit_filter:
	r1 = 31;								/* scale the result back up to MSBs */
	r8 = fix f8 by r1;						/* convert back to fixed point */
	r9 = fix f9 by r1;						/* Convert back to fixed point */
	DM(Left_Channel_Out0) = r8; 			/* send result to AD1836 DACs */
	DM(Right_Channel_Out0) = r9;
	DM(Left_Channel_Out1) = r8; 			/* send result to AD1836 DACs */
	DM(Right_Channel_Out1) = r9;

	rts;
fir.end:

/* ------------------------------------------------------------------------------------ */
/*                                                                                      */
/*                      IRQ2 Pushbutton Interrupt Service Routine                       */
/*                                                                                      */
/* 	This routine determines which FIR filter routine to execute.                      	*/
/* 	Pressing the IRQ1 pushbutton will toggle between each filter. The default           */
/*	is a lowpass filter                                                                 */
/*                                                                                      */
/*	To listen to unfiltered signal, hit the FLAG 3 pushbutton                           */
/* ------------------------------------------------------------------------------------ */

change_filter_coeffs:
    bit set mode1 SRRFH;				/* enable background register file */
	NOP; 								/* 1 CYCLE LATENCY FOR WRITING TO MODE1 REGISER!!   */

	r11 = 2;
	r10 = DM(filter_counter);			/* get last count from memory */
	r10 = r10 + 1;						/* increment preset */
	comp (r10, r11);					/* compare current count to max count */
	if ge r10 = r10 - r10;				/* if count equals max, reset to zero and start over */
	DM(filter_counter) = r10;			/* save updated count */

	r15 = pass r10;						/* get FIR filter preset mode ID */
	if eq jump filter_select_2;			/* check for count == 0 */
	r10 = r10 - 1;
	r10 = pass r10;						

filter_select_1:						/* count therefore, is == 1 if you are here */
	b9 = coef_lo;		l9 = @coef_lo;  /* pointer to the interleaved lowpass filter coefficients  */
	ustat1=dm(IOFLAG);
	bit clr ustat1 0x3E;				/* turn on Flag4 LED */
	bit set ustat1 0x01;
	dm(IOFLAG)=ustat1;
    jump exit_IRQ_routine;

filter_select_2:
	b9 = coef_hi;		l9 = @coef_hi;  /* pointer to the interleaved lowpass filter coefficients  */
	ustat1=dm(IOFLAG);
	bit clr ustat1 0x3D;				/* turn on Flag5 LED */
	bit set ustat1 0x02;
	dm(IOFLAG)=ustat1;		

exit_IRQ_routine:	
	rti(db);
	bit clr mode1 SRRFH;				/* switch back to primary register set */
	nop;
change_filter_coeffs.end:


⌨️ 快捷键说明

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