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

📄 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 132
#define FILTER_TAPS 66
#define HALF_FILTER_TAPS 33


.section /dm    dm_data;

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

.endseg;

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

.section /pm	  pm_data;

.ALIGN 2;
.VAR    coef_lo_300Hz[FILTER_TAPS] = "coeffs65_300Hz.dat";  /* declare and initialize the higpass filter coefficients*/
.ALIGN 2;
.VAR	coef_lo_600Hz[FILTER_TAPS] = "coeffs65_600Hz.dat";	/* declare and initialize the lowpass filter coefficients*/		
.ALIGN 2;
.VAR    coef_hi_4kHz[FILTER_TAPS] = "coeffs65_4kHz.dat";   	/* declare and initialize the higpass filter coefficients*/
.ALIGN 2;
.VAR	coef_hi_8kHz[FILTER_TAPS] = "coeffs65_8kHz.dat";	/* declare and initialize the lowpass filter coefficients*/		


/* "coeffs129_300Hz.dat" & "coeffs129_600Hz.dat" contains the coefficients for a low pass filter and
   "coeffs129_4kHz.dat" & "coeffs129_4kHz.dat" contains the coefficients for a high pass filter */
				
.endseg;


.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_300Hz;	l9 = @coef_lo_300Hz;   	/* pointer to the highpass filter coefficients  */
	m9 = 1 ;

	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.
	bit set mode1 PEYEN | BDCST9;
	bit clr mode1 IRPTEN;

	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 = 4;
	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;						
	if eq jump filter_select_3;			/* check for count == 1 */
	r10 = r10 - 1;
	r10 = pass r10;						
	if eq jump filter_select_4;			/* check for count == 2 */

filter_select_1:						/* count therefore, is == 3 if you are here */
	b9 = coef_lo_300Hz;	l9 = @coef_lo_300Hz;   	/* load 300 Hz 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_lo_600Hz;	l9 = @coef_lo_600Hz;	/* load 600 Hz lowpass filter coefficients  */
	ustat1=dm(IOFLAG);
	bit clr ustat1 0x3D;						/* turn on Flag5 LED */
	bit set ustat1 0x02;
	dm(IOFLAG)=ustat1;		
    jump exit_IRQ_routine;

filter_select_3:					
	b9 = coef_hi_4kHz;	l9 = @coef_hi_4kHz;   	/* load 4000 Hz highpass filter coefficients  */
	ustat1=dm(IOFLAG);
	bit clr ustat1 0x3B;						/* turn on Flag6 LED */
	bit set ustat1 0x04;
	dm(IOFLAG)=ustat1;
    jump exit_IRQ_routine;

filter_select_4:
	b9 = coef_hi_8kHz;	l9 = @coef_hi_8kHz;   	/* load 8000 Hz highpass filter coefficients */
	ustat1=dm(IOFLAG);
	bit clr ustat1 0x37;						/* turn on Flag7 LED */
	bit set ustat1 0x08;
	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 + -