📄 filter.asm
字号:
;****************************************************************
; Function: dlms
; Version: 1.00
; Description: dlms fir filter
;
; Copyright Texas instruments Inc, 1998
;----------------------------------------------------------------
; Revision History:
; 1.00, R. Piedra, 8/31/98 - Original release. Started from code by
; Padma Mallela.
;****************************************************************
.mmregs
; Far-mode adjustment
.if __far_mode
offset .set 1 ; far mode uses one extra location for ret addr ll
.else
offset .set 0
.endif
.asg (0), mu_error ; 2*mu*error(i) variable
.asg (1), save_st1 ; stack description
.asg (2), save_st0
.asg (3), save_ar6
.asg (4), save_ar1
.asg (5), ret_addr
; x in A
.asg (6 + offset), arg_h
.asg (7 + offset), arg_y
.asg (8 + offset), arg_d
.asg (9 + offset), arg_des
.asg (10 + offset), arg_rate
.asg (11 + offset), arg_nh
.asg (12 + offset), arg_n
; register usage
; AR0 : circ addr. index
.asg ar1, ar_count
.asg ar2, ar_d
.asg ar3, ar_h
.asg ar4, ar_des
.asg ar5, ar_x
.asg ar6, ar_y
;*****************************************************************************
.def _dlms
_dlms:
; Preserve registers
;-------------------
pshm ar1
pshm ar6
PSHM ST0 ; 1 cycle
PSHM ST1 ; 1 cycle
RSBX OVA ; 1 cycle
RSBX OVB ; 1 cycle
; Preserve space for local variables
; ----------------------------------
frame -1 ; mu_error local var
; Set math and overflow modes
;---------------------------
ssbx SXM ; sign extension on
ssbx frct ; fract on
ld #0,ASM ; clear ASM (used by st||mpy)
st #0, *sp(mu_error) ; clear error OJO : make argument
;
; Get arguments
;---------------
stlm a, ar_x ; pointer to x
mvdk *sp(arg_h),*(ar_h) ; pointer to h
mvdk *sp(arg_y),*(ar_y) ; pointer to y
mvdk *sp(arg_d),*(ar_d) ; de-referencing
mvdk *ar_d,*(ar_d) ; pointer to d
mvdk *sp(arg_des),*(ar_des) ; for circ addr
mvdk *sp(arg_n), *(ar_count) ; sample counter
mar *ar_count- ; ar_count= nsamples-1
ld *sp(arg_nh),a ; a = nh
; Initialize registers
; --------------------
stlm a,bk ; bk = circular buffer size = nh
stm #1,AR0
sub #03,a
_start:
stl a, *sp(arg_nh)
; Loop through remaining (n-1) samples
;-------------------------------------
next_sample:
mvdk *sp(arg_nh),brc
ld *sp(mu_error), t ; t = 2 * mu * error (i)
sub b,b ; b = 0
; Loop through (nh-2) taps: compute filter and adapt at = time
; ------------------------------------------------------------
rptbd lms_end -1
mpy *ar_d+0%,a ; a = mu_error * x(1)
; point to x(2)
lms *ar_h, *ar_d ; b = b + h(1) * x(2)
; a = a + h(1)
lms_beg
st a, *ar_h+0%; ; update h(1)
; point to h(2)
|| mpy *ar_d+0%,a ; a = mu_error * x(2)
; point to x(0)
lms *ar_h, *ar_d ; b = b + h(2) * x(0)
; a = a + h(2)
lms_end
; Perform 1st tap outside to avoid that the oldest
; sample is over written before updating the h(0) coef
; ----------------------------------------------------
st a, *ar_h+0% ; update last coef
|| mpy *ar_d+0%,a ; error * x(0)
mvdd *ar_x+, *ar_d ; new sample --> dbuffer x(0)
lms *ar_h, *ar_d+0% ; b = b * h(0) * x(1)
; Write output sample
; -------------------
sth b, *ar_y+
; Compute new error
; ----------------
st a,*ar_h+0%
|| sub *ar_des+,a ; bh = error(i)= des(i)-y(i)
banzd next_sample, *ar_count
mpya *sp(arg_rate) ; b = step_size * error(i)
sth b, *sp(mu_error) ; save as local variable
; Return
;-------
_end
.asg ar_h, ar_temp ; ar_h not used any more
mvdk *sp(arg_d), *(ar_temp)
mvkd *(ar_d), *ar_temp ; update new ar_d
; Return overflow flag
; --------------------
ld 0,a
xc 1,AOV
ld #1,a
; Adjust stack pointer and restore registers
; ------------------------------------------
frame +1 ; adjust for local vars
POPM ST1 ; 1 cycle
POPM ST0 ; 1 cycle
popm ar6
popm ar1
.if __far_mode
fretd
.else
retd
.endif
nop
nop
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -