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

📄 dtmfasm.s55

📁 Express DSP compliant C55x DTMF detector software is proposed in two versions: one with a 5 ms frame
💻 S55
📖 第 1 页 / 共 2 页
字号:
*-------------------------------------------------------------------------*
*                                                                         *
*   THIS IS AN UNPUBLISHED WORK CONTAINING CONFIDENTIAL AND PROPRIETARY   *
*   INFORMATION.  IF PUBLICATION OCCURS, THE FOLLOWING NOTICE APPLIES:    *
*      "COPYRIGHT 2001 MIKET DSP SOLUTIONS, ALL RIGHTS RESERVED"          *
*                                                                         *
*-------------------------------------------------------------------------*
    .mmregs
    .arms_on
    .cpl_on
    .include "dtmfi.h55"

    .sect ".dtmf_d"
__apsLoDev		.long	_dtmf_a697,  _dtmf_a770,  _dtmf_a852,  _dtmf_a941
__apsHiDev		.long	_dtmf_a1209, _dtmf_a1336, _dtmf_a1477, _dtmf_a1633
__aasLoDevFlt	.word 23220, 77,    18493, 90,    14473, 112, 11353, 139
__aasHiDevFlt	.word 16916, 100,   12640, 115,   9888,  139, 7614,  175
_dtmf_as2k		.word 1230,  -2060, 3472,  -6516, 20712

	.text

;-------------------------------------------------------------------------

macro_en2log   .macro acc, treg

;-------------------------------------------------------------------------

    acc = acc + #1;
    acc = mant (acc), treg = -exp(acc);
    acc = acc << #-21;
    acc = acc + #0x780;
    acc = acc + (treg*#512);
    .endm

;-------------------------------------------------------------------------
	.global _dtmf_en2log
_dtmf_en2log
;-------------------------------------------------------------------------
;
; function call arguments
;	ac0 = energy
;
; function returns
;	t0  =  energy in log 
;
	macro_en2log	ac0, t0
	t0 = ac0
	return

;-------------------------------------------------------------------------
	.global _dtmf_filter_test
_dtmf_filter_test
;-------------------------------------------------------------------------
;
; function call arguments
;	ar0 = DTMF_tDb *pDb,
;	ar1 = DTMF_tSc *pSc,
;	ar2 = S16 *psIn
;
	.arms_off
	bit(ST2, #ST2_ARMS) = #0;

	push	(t2)
	push	(t3)

;
; move as2kData
	xar3 = mar(*ar0(#(DTMF_tDb.as2kDataSav)));
	xar4 = mar(*ar1(#(DTMF_tSc.as2kData)))
	repeat (#(DTMF_2KFLT_SZ-1))
		*ar4+ = *ar3+					; ar2->Db.asBpDataSav
										; ar3->Sc.asBpData
;
; add new data
	mar (t2 = #-3);
	ac0 = *ar2+ << #16
	|| repeat (#(IDTMF_FR_SZ-2))
		ac0 = *ar2+ << #16, *ar4+ = HI(ac0<<t2);
	*ar4+ = HI(ac0<<#-3);
;
; move bp saved data
	|| repeat (#(DTMF_BPFLT_SZ-1))
		*ar4+ = *ar3+
;
; move lo dft saved data
	xar4 = mar(*ar1(#(DTMF_tSc.asLoData)))
	repeat (#(DTMF_LOSD_SZ-1))
		*ar4+ = *ar3+
	.if (IDTMF_FR_SZ != 80)		
;
; move hi dft saved data
	xar4 = mar(*ar1(#(DTMF_tSc.asHiData))); ar3->Sc.asHiData
	repeat	(#(DTMF_HISD_SZ-1))
		*ar4+ = *ar3+  
	.endif
										; ar2->Db->asSumEn
;
; delay sum energy
	xar3 = mar(*ar0(#(DTMF_tDb.v.asSumEn+4)))
	repeat (#4)
		delay(*ar3-)
;
; --- 2k filter ---
;
    t1  = #2;
	t0  = #(-DTMF_2KFLT_HSZ+1);
;
; xar2 = pOut
	xar2 = mar(*ar1(#(DTMF_tSc.asBpData+DTMF_BPFLT_SZ)));
;
; xar3 = pPos
	xar3 = mar(*ar1(#(DTMF_tSc.as2kData)));
;
; xar4 = pNeg
	xar4 = mar(*ar1(#(DTMF_tSc.as2kData+DTMF_2KFLT_HSZ*4-2)));
;
; xcdp = coeffs
    xcdp = #_dtmf_as2k;
;
    ac3 = #0;
    brc0 = #(IDTMF_FR_SZ/2-1)
    ac0 = #0;
    || localrepeat {
        ac1 = *(ar3+t1) * coef(*cdp+), 
        ac2 = *(ar4-t1) * coef(*cdp+);
        || repeat (#(DTMF_2KFLT_HSZ-3))
            ac1 = ac1 + (*(ar3+t1) * coef(*cdp+)),
            ac2 = ac2 + (*(ar4-t1) * coef(*cdp+));
        ac1 = ac1 + (*ar3+ * coef(*(cdp+t0))),
        ac2 = ac2 + (*(ar4-t1) * coef(*(cdp+t0)));
										; ar3 -> central tap
										; cdp -> back to fisrt coeff
        ac1 = ac1 + ac2;

        ac1 = ac1 + (*ar3 << #15);
        
        ac2 = ac1 - (*ar3+ << #16);
        ||mar(ar4 + #(DTMF_2KFLT_HSZ*2+2))
        
        ac3 = ac3 + (ac2 * ac2);
        ||mar(ar3 - #(DTMF_2KFLT_HSZ*2-2))
        
        ac0 = ac0 + (ac1 * ac1);
        ||  *ar2+ = HI(ac1);
    }									; [10*20 = 200 cycles]
    macro_en2log    ac0, t0
    macro_en2log    ac3, t0
    ac0 = ac0 - ac3;
	*ar1(#(DTMF_tSc.s2kEnDlt)) = ac0; 
;
; --- lo bp filter
;
; ar2 = dst ptr
	xar2 = mar(*ar1(#(DTMF_tSc.asLoData + DTMF_LOSD_SZ)));
;
; ar3 = I filter
	xar3 = #_dtmf_aLoBpI
;
; ar4 = Q filter
	xar4 = #_dtmf_aLoBpQ
;
; cdp = input data
    xcdp = mar(*ar1(#(DTMF_tSc.asBpData)))
;
    t1 = #(-DTMF_BPFLT_SZ+1);
    t0 = #(-DTMF_BPFLT_SZ+DTMF_BPDR+1);
    brc0 = #(DTMF_DFR_SZ-1);
; ac0 = energy
    ac0 = #0
    || localrepeat {
        ac1 = *ar3+ *coef(*cdp+), ac2 = *ar4+ *coef(*cdp+)
        || repeat (#(DTMF_BPFLT_SZ-3))
            ac1 = ac1 + (*ar3+ * coef(*cdp+)), 
			ac2 = ac2 + (*ar4+ * coef(*cdp+))
        ac1 = ac1 + (*(ar3+t1) * coef(*(cdp+t0))), 
		ac2 = ac2 + (*(ar4+t1) * coef(*(cdp+t0)))

        *ar2+ = HI(ac1) 
        || ac0 = ac0 + (ac1 * ac1);

        *ar2+ = HI(ac2)
        || ac0 =  ac0 + (ac2 * ac2);
    }									; [(BP_FLT_SZ+2)*4]    
    .if (IDTMF_FR_SZ == 40)
    .else 
    ac0 = ac0 >> #1;
	.endif    
	dbl(*ar1(#(DTMF_tSc.slLoBpEn))) = ac0;
	macro_en2log	ac0, t2
	*ar1(#(DTMF_tSc.sLoBpEn)) = ac0;
	
;
; --- hi bp filter ---
;
	xar2 = mar(*ar1(#(DTMF_tSc.asHiData + DTMF_HISD_SZ)));
	xar3 = #_dtmf_aHiBpI
	xar4 = #_dtmf_aHiBpQ
	brc0 = #(DTMF_DFR_SZ-1);
	xcdp = mar(*ar1(#(DTMF_tSc.asBpData)))

    ac0 = #0;
    || localrepeat {
        ac1 = *ar3+ *coef(*cdp+), ac2 = *ar4+ *coef(*cdp+)
        || repeat (#(DTMF_BPFLT_SZ-3))
            ac1 = ac1 + (*ar3+ * coef(*cdp+)), 
			ac2 = ac2 + (*ar4+ * coef(*cdp+))
        ac1 = ac1 + (*(ar3+t1) * coef(*(cdp+t0))), 
		ac2 = ac2 + (*(ar4+t1) * coef(*(cdp+t0)))

        *ar2+ = HI(ac1) 
        || ac0 = ac0 + (ac1 * ac1);

        *ar2+ = HI(ac2)
        || ac0 =  ac0 + (ac2 * ac2);
    }									; [(BP_FLT_SZ+2)*4]
    .if (IDTMF_FR_SZ == 40)
    .else 
    ac0 = ac0 >> #1;
	.endif    
	dbl(*ar1(#(DTMF_tSc.slHiBpEn))) = ac0;
	macro_en2log	ac0, t2
	*ar1(#(DTMF_tSc.sHiBpEn)) = ac0;
;
; sum energy
;
	ac0 = dbl(*ar1(#(DTMF_tSc.slLoBpEn)));
	ac0 = ac0 + dbl(*ar1(#(DTMF_tSc.slHiBpEn)));
	macro_en2log	ac0, t0
	*ar1(#(DTMF_tSc.sSumEn)) = ac0;
	*ar0(#(DTMF_tDb.v.asSumEn)) = ac0;
;
; --- dial filter --- 
;
; ar3 -> I filter
	xar3 = #_dtmf_aDialI
;
; ar4 -> Q filter
	xar4 = #_dtmf_aDialQ
;
; cdp = ptr to in data
	xcdp = mar(*ar1(#(DTMF_tSc.asBpData)));
;
; t0 = bigger step back (t1 the same {filter_len-1})
    t0   = #(-DTMF_BPFLT_SZ+DTMF_BPDR*2+1);

    brc0 = #(DTMF_DFR_SZ/2-1);
    ac0 = #0;
    || localrepeat {
        ac1 = *ar3+ *coef(*cdp+), ac2 = *ar4+ * coef(*cdp+);
        || repeat (#(DTMF_BPFLT_SZ-3))
            ac1 = ac1 + (*ar3+ * coef(*cdp+)), 
			ac2 = ac2 + (*ar4+ * coef(*cdp+));
        ac1 = ac1 + (*(ar3+t1) * coef(*(cdp+t0))), 
		ac2 = ac2 + (*(ar4+t1) * coef(*(cdp+t0)));

        ac0 = ac0 + (ac1*ac1);
        ac0 = ac0 + (ac2*ac2);
    }									; [(BP_FLT_SZ+2)*2]
	dbl(*ar1(#(DTMF_tSc.slDialEn))) = ac0;

	.if (IDTMF_FR_SZ == 80)
	ac1 = ac0;
	macro_en2log	ac1, t2
	*ar1(#(DTMF_tSc.sDialEn)) = ac1;
	.endif
;
; --- sum energies up ---
;
	.if (IDTMF_FR_SZ == 40)
	ac1 = ac0 + dbl(*ar0(#(DTMF_tDb.v.slDialEn)));
	.else
	ac1 = ac0;
	.endif
	ac1 = ac1 + dbl(*ar1(#(DTMF_tSc.slLoBpEn)));
	ac1 = ac1 + dbl(*ar1(#(DTMF_tSc.slHiBpEn)));
	macro_en2log	ac1, t2
	*ar1(#(DTMF_tSc.sSumDialEn)) = ac1; 
	
	.if (IDTMF_FR_SZ == 40)
	dbl(*ar0(#(DTMF_tDb.v.slDialEn))) = ac0;
	.endif
;
; -- lo band dft
;
;	ar2 =  psOut
;   ar3 = psI data
;   ar4 = psQ data
;   t1 = sSz*2-1
;   cdp = filterbank
;   t0 = 2
;   ac2 = energy, both lin and log
;
	xar2 = mar(*ar1(#(DTMF_tSc.asLoMainEn)));
	xar3 = mar(*ar1(#(DTMF_tSc.asLoData)));
	xar4 = mar(*ar1(#(DTMF_tSc.asLoData+1)));
	xcdp = #_dtmf_aLo;
    mar	(t1 = #(DTMF_LO_DFT_SZ*2-2))
    brc0 = #(4-1)

	mar	(t0 = #2);
    || localrepeat {
        ac0 = *(ar3+t0) * coef( *cdp+), 
		ac1 = *(ar4+t0) * coef(*cdp+);
        || repeat(#(DTMF_LO_DFT_SZ-3))
            ac0=ac0+(*(ar3+t0)*coef(*cdp+)), 
			ac1=ac1+(*(ar4+t0)*coef(*cdp+));
        ac0 = ac0+(*(ar3-t1)*coef(*cdp+)), 
		ac1 = ac1+(*(ar4-t1)*coef(*cdp+));
        || repeat(#(DTMF_LO_DFT_SZ-2))
            ac0 = ac0-(*(ar4+t0)*coef(*cdp+)), 
			ac1 = ac1+(*(ar3+t0)*coef(*cdp+));
        ac0 = ac0-(*(ar4-t1)*coef(*cdp+)), 
		ac1 = ac1+(*(ar3-t1)*coef(*cdp+));

        ac2=ac0*ac0;
        ac2=ac2+(ac1*ac1);
        macro_en2log    ac2, t2;		; [5]
        *ar2+ = ac2;
    }									; [(DFT_SZ*2+8)*4]
;
; -- sort lo frequencies ---
;
	mar	 (ar2 - #4)
    || t2   = #0
    ac3  = #0;
    || brc0 = #(4-2);    

    ac0  = *ar2+
    || localrepeat {
        ac1 = *ar2+ || ac3 = ac3 + #1;
        ac0 = max (ac1, ac0)                ; carry = 0 if ac1>ac0
        if (!CARRY) execute(D_unit)         ; 
            || t2 = ac3
    }
;
; t3 = ac0 = max of all freqs
; t2 =  max idx
    *ar1(#(DTMF_tSc.sLoFreqNo)) = t2;
    t3  = ac0;
    || mar  (ar2 - #4); 
    ac0	 = #-32767;
    brc0 = #(4-1);    
    
	.if 0   ; OLD CODE, comparing EN = MAX instead of idx.
			; that fails if there are 2 equal max energies
	

    localrepeat {
        ac1 = *ar2+ - t3;
        || bit(st0, #ST0_CARRY) = #1;
        if(ac1 != #0) execute(D_unit)
           || ac0 = max(ac1, ac0);            ; carry = 0 if ac1>ac0
        if(!CARRY) execute(D_unit)
            || ac2 = ac0;
    }
    ac2 = ac2 + t3;
    
    .else ; CORRECTION of 2002/11/20
    
    localrepeat {
    	ac1 = *ar2+
    	|| bit(st0, #ST0_CARRY) = #1;
    	if (t2 != #0) execute(D_unit)
    		|| ac0 = max(ac1, ac0);
    	if (!CARRY) execute(D_unit)
    		|| ac2 = ac0;
    	t2 = t2 - #1;
    }
    t2 = t2 + #4; return t2 back
    
    .endif
    
    *ar1(#(DTMF_tSc.sLoNextEn)) = ac2;
;
; -- lo band dft for deviations
;
;   cdp = filterbank
;   t0 = 2
;   ac2 = energy, both lin and log
;
	xar2 = #__apsLoDev;
	mar	(ar2+t2);
	mar	(ar2+t2);						; long (2 w) storage for 
										; large data mem model
	xcdp = dbl(*ar2);

	xar2 = mar(*ar1(#(DTMF_tSc.asLoDevEn)));

    brc0 = #(4-1)
    localrepeat {
        ac0 = *(ar3+t0) * coef( *cdp+), 
		ac1 = *(ar4+t0) * coef(*cdp+);
        || repeat(#(DTMF_LO_DFT_SZ-3))
            ac0=ac0+(*(ar3+t0)*coef(*cdp+)), 
			ac1=ac1+(*(ar4+t0)*coef(*cdp+));
        ac0 = ac0+(*(ar3-t1)*coef(*cdp+)), 
		ac1 = ac1+(*(ar4-t1)*coef(*cdp+));
        || repeat(#(DTMF_LO_DFT_SZ-2))
            ac0 = ac0-(*(ar4+t0)*coef(*cdp+)), 
			ac1 = ac1+(*(ar3+t0)*coef(*cdp+));
        ac0 = ac0-(*(ar4-t1)*coef(*cdp+)), 
		ac1 = ac1+(*(ar3-t1)*coef(*cdp+));

        ac2=ac0*ac0;
        ac2=ac2+(ac1*ac1);
        macro_en2log    ac2, t2;		; [5]
        *ar2+ = ac2;
    }									; [(DFT_SZ*2+8)*4]
;
; --- get lo band frequency deviation
;
; ar2 = psDev
; ar3 = psDevFlt
;
	t2 = *ar1(#(DTMF_tSc.sLoFreqNo))
	mar (ar2 - #4);						; return ptr back
	xar3 = #__aasLoDevFlt;
	mar (ar3+t2);
	mar (ar3+t2);

    ac0 = *ar2(#3)
    ac0 = ac0 - *ar2; /* offset 0 */
    ac0 = ac0 + *ar2(#2)
    ac0 = ac0 - *ar2(#1)
    ac0 = ac0 << #16;
    ac0 = *ar3+ * ac0;
    
	ac1 = #(170*5) << #16;
	ac0 = min(ac1, ac0);
	ac1 = #(-170*5) << #16;
	ac0 = max(ac1, ac0);
	
    *ar1(#(DTMF_tSc.sLoFreqDev)) = HI(ac0);

    ac0 = ac0*ac0;

⌨️ 快捷键说明

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