c2000ware-core-sdk/libraries/dsp/FixedPoint/c28/source/fir16.asm
2023-12-13 16:46:16 +05:30

237 lines
10 KiB
NASM

;;#############################################################################
;;! \file source/fir16.asm
;;!
;;! \brief 16-bit FIR filter
;;!
;;! \date May 11, 2010
;;!
;;
;;#############################################################################
;;!
;;! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
;;! All rights reserved not granted herein.
;;! Limited License.
;;!
;;! Texas Instruments Incorporated grants a world-wide, royalty-free,
;;! non-exclusive license under copyrights and patents it now or hereafter
;;! owns or controls to make, have made, use, import, offer to sell and sell
;;! ("Utilize") this software subject to the terms herein. With respect to the
;;! foregoing patent license, such license is granted solely to the extent that
;;! any such patent is necessary to Utilize the software alone. The patent
;;! license shall not apply to any combinations which include this software,
;;! other than combinations with devices manufactured by or for TI
;;! ("TI Devices").
;;! No hardware patent is licensed hereunder.
;;!
;;! Redistributions must preserve existing copyright notices and reproduce this
;;! license (including the above copyright notice and the disclaimer and
;;! (if applicable) source code license limitations below) in the documentation
;;! and/or other materials provided with the distribution.
;;!
;;! Redistribution and use in binary form, without modification, are permitted
;;! provided that the following conditions are met:
;;!
;;! * No reverse engineering, decompilation, or disassembly of this software is
;;! permitted with respect to any software provided in binary form.
;;! * Any redistribution and use are licensed by TI for use only
;;! with TI Devices.
;;! * Nothing shall obligate TI to provide you with source code for the
;;! software licensed and provided to you in object code.
;;!
;;! If software source code is provided to you, modification and redistribution
;;! of the source code are permitted provided that the following conditions
;;! are met:
;;!
;;! * any redistribution and use of the source code, including any resulting
;;! derivative works, are licensed by TI for use only with TI Devices.
;;! * any redistribution and use of any object code compiled from the source
;;! code and any resulting derivative works, are licensed by TI for use
;;! only with TI Devices.
;;!
;;! Neither the name of Texas Instruments Incorporated nor the names of its
;;! suppliers may be used to endorse or promote products derived from this
;;! software without specific prior written permission.
;;#############################################################################
;;
;;*****************************************************************************
;; includes
;;*****************************************************************************
;;
;;*****************************************************************************
;; globals
;;*****************************************************************************
; Module definition for external reference
.if __TI_EABI__
.asg FIR16_init, _FIR16_init
.asg FIR16_calc, _FIR16_calc
.endif
.def _FIR16_init
.def _FIR16_calc
;;
;;=============================================================================
;; Routine Type : C Callable
;; Description :
;; void FIR16_calc(FIR16_handle)
;;
;; This routine implements the non-recursive difference equation of an
;; all-zero filter(FIR), of order N. All the coefficients of all-zero
;; filter are assumed to be less than 1 in magnitude.
;;=============================================================================
;;
;; Algorithm: Y = sat(X0*C0 + X1*C1 + X2*C2 + ... Xn*Cn) >> 15
;; Xn = Xn-1
;; .
;; .
;; X2 = X1
;; X1 = X0
;;
;; X0 = input, Q15
;; X1,..,Xn = Data, Q15
;; C0,..,Cn = Coef, Q15
;; Y = output, Q15
;; n = N - 1 (N = number of taps, must always be an even number)
;;
;; This program uses the Dual-MAC capability of the C28x. The data
;; and coef structures must be organized into 32-bit words as follows:
;;
;; 31 16 15 0
;; +------------+------------+
;; *Data -> | N-2 | Index | 0 lowest address
;; | SatMax | 2
;; | SatMin | 4
;; | unused | (N/2)-1 | 6
;; +------------+------------+
;; | . | . | 0
;; | . | . | 2
;; tail-> | . | X(1) | 4
;; head-> | X((n+1)/2) | X(0) | 6<- index value before
;; | X(n) | X((n-1)/2) | 8 executing FIR
;; | X(n-1) | . | .
;; | . | . | .
;; +------------+------------+
;;
;; 31 16 15 0
;; +------------+------------+
;; *Coef -> | C(n) | C((n-1)/2) | 0 lowest address
;; | C(n-1) | . | 2
;; | . | . | 4
;; | . | C(2) | .
;; | . | C(1) | .
;; | C((n+1)/2) | C(0) | .
;; +------------+------------+
;;
;; * For maximum performance, locate Data & Coef
;; structures in seperate RAM blocks.
;; * The Data & Coef pointers must always point to the lowest
;; address of the array and always aligned to even address
;;
;; Before calling FIR, need to initialize following data parameters:
;;
;; Index = 0
;; N = Number of filter taps (must always be even)
;; N-2 = Size of data buffer (must always be an even number)
;; (N/2)-1 = number of times to repeat Dual MAC operation
;; SatMax = 0x00FFFFFF (corresponds to SPM of -6)
;; SatMin = 0xFF000000 (corresponds to SPM of -6)
;;
;; Note: Don't forget to clear all data values
;==============================================================================
;; Function Input: This function accepts the handle of the below structure
;;
;; typedef struct { <------------ XAR4
;; int32_t *coeff_ptr; /* +0 Pointer to Filter coefficient */
;; int32_t * dbuffer_ptr; /* +2 Delay buffer ptr */
;; int16_t cbindex; /* +4 Circular Buffer Index */
;; int16_t order; /* +5 Order of the Filter */
;; int16_t input; /* +6 Latest Input sample */
;; int16_t output; /* +7 Filter Output */
;; void (*init)(void *); /* +8 Ptr to Init funtion */
;; void (*calc)(void *); /* +10 Ptr to calc fn */
;; }FIR16;
;;
_FIR16_init:
MOV *+XAR4[6],#0 ; XAR4->ouput, input=0
MOV *+XAR4[7],#0 ; output=0
MOVL XAR6,*+XAR4[2] ; XAR6=dbuffer_ptr
MOV AL,*+XAR4[5] ; AL=order
MOV AH,AL ; AH=order
TBIT AL,#0
ADDB AL,#1 ; AL=order+1
MOV AL,AH,TC ; AL=order, if odd
MOV AH,AL
SUBB AH,#1
MOV *+XAR4[4],AH ; cbindex = order, even
; = order-1, odd
RPT AL
|| MOV *XAR6++,#0
LRETR
ConstTable:
PosSatVal: .long 0x00FFFFFF ; Corresponds to >> 6
NegSatVal: .long 0xFF000000 ; Corresponds to >> 6
;;FILTER_ORDER .set 43
;;RPT_COUNT .set (FILTER_ORDER/2)
_FIR16_calc:
PUSH XAR1 ; Context Save
SETC SXM,OVM ; AR4=FIR16_handle->coeff_ptr
SPM -6 ; Create guard band of >> 6
MOVL XAR7,*XAR4 ; XAR4->coeff_ptr, XAR7=coeff_ptr
MOVZ AR1,*+XAR4[4] ; XAR4->coeff_ptr, AR1=cbindex
MOVL XAR6,*+XAR4[2] ; XAR4->coeff_ptr, XAR6=dbuffer_ptr
MOVL ACC,*XAR6 ; ACC = -:X
MOV AH,@AL ; ACC = X:X
MOV AL,*+XAR4[6] ; ACC = X:Input
MOVL *XAR6%++,ACC ; Store in data array and inc circ address
MOVL *+XAR4[2],XAR6 ; XAR4->coeff_ptr, update the dbuffer pointer
MOV ACC,*+XAR4[5]<<15 ; AR0=cbindex
MOVZ AR0,AH ; AR0=order/2
ZAPA ; Zero the ACC, P registers and OVC counter
;; <<VC140828 - debug only
;;.asg 0, N
;;.loop
;;DMAC ACC:P,*XAR6%++,*XAR7++ ; XT = *+XAR6[AR1%++], Temp = *XAR7++
;; ; ACC = (XT.MSW*Temp.MSW) << PM (>> -6)
;; ; P = (XT.LSW*Temp.LSW) << PM (>> -6)
;;.eval N + 1, N ; increment N
;;.break N = (RPT_COUNT+1)
;;.endloop
;; VC140828>>
RPT AR0
|| DMAC ACC:P,*XAR6%++,*XAR7++
ADDL ACC,P ; Add the two sums with shift
MOVW DP,#PosSatVal
MINL ACC,@PosSatVal ; Saturate result
MOVW DP,#NegSatVal
MAXL ACC,@NegSatVal
MOVH *+XAR4[7],ACC<<7 ; Store saturated result (Q15)
SPM 0
POP XAR1
CLRC OVM
LRETR
;;#############################################################################
;; End of File
;;#############################################################################