📄 msp430f169_fir.s43
字号:
;// THIS PROGRAM IS PROVIDED "AS IS". TI MAKES NO WARRANTIES OR
;// REPRESENTATIONS, EITHER EXPRESS, IMPLIED OR STATUTORY,
;// INCLUDING ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
;// FOR A PARTICULAR PURPOSE, LACK OF VIRUSES, ACCURACY OR
;// COMPLETENESS OF RESPONSES, RESULTS AND LACK OF NEGLIGENCE.
;// TI DISCLAIMS ANY WARRANTY OF TITLE, QUIET ENJOYMENT, QUIET
;// POSSESSION, AND NON-INFRINGEMENT OF ANY THIRD PARTY
;// INTELLECTUAL PROPERTY RIGHTS WITH REGARD TO THE PROGRAM OR
;// YOUR USE OF THE PROGRAM.
;//
;// IN NO EVENT SHALL TI BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
;// CONSEQUENTIAL OR INDIRECT DAMAGES, HOWEVER CAUSED, ON ANY
;// THEORY OF LIABILITY AND WHETHER OR NOT TI HAS BEEN ADVISED
;// OF THE POSSIBILITY OF SUCH DAMAGES, ARISING IN ANY WAY OUT
;// OF THIS AGREEMENT, THE PROGRAM, OR YOUR USE OF THE PROGRAM.
;// EXCLUDED DAMAGES INCLUDE, BUT ARE NOT LIMITED TO, COST OF
;// REMOVAL OR REINSTALLATION, COMPUTER TIME, LABOR COSTS, LOSS
;// OF GOODWILL, LOSS OF PROFITS, LOSS OF SAVINGS, OR LOSS OF
;// USE OR INTERRUPTION OF BUSINESS. IN NO EVENT WILL TI'S
;// AGGREGATE LIABILITY UNDER THIS AGREEMENT OR ARISING OUT OF
;// YOUR USE OF THE PROGRAM EXCEED FIVE HUNDRED DOLLARS
;// (U.S.$500).
;//
;// Unless otherwise stated, the Program written and copyrighted
;// by Texas Instruments is distributed as "freeware". You may,
;// only under TI's copyright in the Program, use and modify the
;// Program without any charge or restriction. You may
;// distribute to third parties, provided that you transfer a
;// copy of this license to the third party and the third party
;// agrees to these terms by its first use of the Program. You
;// must reproduce the copyright notice and any other legend of
;// ownership on each copy or partial copy, of the Program.
;//
;// You acknowledge and agree that the Program contains
;// copyrighted material, trade secrets and other TI proprietary
;// information and is protected by copyright laws,
;// international copyright treaties, and trade secret laws, as
;// well as other intellectual property laws. To protect TI's
;// rights in the Program, you agree not to decompile, reverse
;// engineer, disassemble or otherwise translate any object code
;// versions of the Program to a human-readable form. You agree
;// that in no event will you alter, remove or destroy any
;// copyright notice included in the Program. TI reserves all
;// rights not specifically granted under this license. Except
;// as specifically provided herein, nothing in this agreement
;// shall be construed as conferring by implication, estoppel,
;// or otherwise, upon you, any license or other right under any
;// TI patents, copyrights or trade secrets.
;//
;// You may not use the Program in non-TI devices.
;//
;-------------------------------------------------------------------------------
; Self contained demo code showing FIR filters
; FIR implementation using DMA channels for maximum performance of the filter.
; Requires 2*TAPNO word RAM buffer for input samples to minimize circular
; buffer overhead
; DMA ch. 0 used to move FIR filter coef from Program mem table to MULS register
; DMA ch. 1 used to move FIR up sample pointer.
; DMA ch.2 used to move FIR down sample pointer
; All three DMAs are enabled and disabled together by modulating
; TACCR0 register is toggled between 0(disable) and 0xb (trigger every 12 clocks).
; This scheme takes advantage of symmetrical nature of coef. The algorithm loads
; a coefficient value once to MPYS via DMA ch 0, then moves two samples
; sequentially to OP2. The first sample is controlled by ch 1 and second by ch 2.
; ch 1 scans through 1/2 sample window by incrementing and ch 2 scans through
; second half sample window by decrementing.
; The Code written such that there is some foreground processor resources while
; the FIR is running at highest possible sample rate.
; Only 1/2 of the coefficients are stored in flash. If the number of taps is even,
; then exactly the first half are stored. If the number of taps is odd, then the
; number of coefficients stored is (N+1)/2 and the last coef value must be divided
; by two.
; Adapted from Code originally written by Alva Henderson
; Murugavel Raju
; 10/31/2003 Version 0.0
; 10/23/2004 Version 0.1
;-------------------------------------------------------------------------------
#include "msp430x16x.h" ; MSP430f169 definitions
#include "sine8192_12b.dat" ; 8192 pt sinewave table
; 12 bit resolution
;-------------------------------------------------------------------------------
RSEG DATA16_N ; RAM Allocation
EVEN
;-------------------------------------------------------------------------------
; Global variables
UP DS 2 ; Temp Up pointer
DN DS 2 ; Temp Down pointer
COEFNO DS 2 ; Number of coefficients
FREQINC DS 2 ; Sweep input resolution
BASE DS 2 ; Time base for input frequency
SWCNTR DS 2 ; Sweep counter
SWRATE DS 2 ; Input sweep rate variable
PDN_INIT DS 2 ; Up pointer
PUP_INIT DS 2 ; Down pointer
INPUT DS 2 ; Input data
SAMPBUF DS 2 ; Pointer to sample buffer
; INPUT sine wave constants to set sweep start freq, stop freq and sweep rate
FREQMAX EQU 8192/2 ; freq = sample freq/2
FREQMIN EQU 10 ; freq = sample freqX10/8192
TMAPER EQU 0x0b ; set Timer_A interval to
; trigger DMA and execute FIR
;-------------------------------------------------------------------------------
RSEG CSTACK ; CPU stack
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
RSEG CODE ; Place code in program memory
EVEN
;-------------------------------------------------------------------------------
Main mov.w #SFE(CSTACK),SP ; Initialize stackpointer
mov.w #WDTHOLD+WDTPW,&WDTCTL ; Stop watchdog timer
SetupBC bic.b #XT2OFF,&BCSCTL1 ; XT2 = on
SetupOsc bic.b #OFIFG,&IFG1 ; Clear OSC fault flag
mov.w #0FFh,R15 ; R15 = Delay
SetupOsc1 dec.w R15 ; delay to ensure start
jnz SetupOsc1 ;
bit.b #OFIFG,&IFG1 ; OSC fault flag set?
jnz SetupOsc ; OSC Fault, clear flag again
bis.b #SELM1+SELS,&BCSCTL2 ; MCLK = SMCLK = XT2 (safe)
RAMCLEAR mov.w #1000,R4 ; Number of RAM locations to clear
mov.w #0200h,R5 ; RAM start
ZERORAM clr.w 0(R5) ; Clear address pointed by R5
add.w #0x2,R5 ; Next word
dec.w R4
jnz ZERORAM
mov.w &SWRATE,30 ; Value for Sweep rate
CLEARFMULT
clr.w &RESHI ; Clear multiplier result registers
clr.w &RESLO
;address pointers for ch 1 and ch 2 depend on if taps are even or odd
INITPTR mov.w &(FILTER+2),R4 ; read number of taps from table
add.w #0x0,R4 ; Clear carry flag
rrc.w R4 ; Calculate actual coef number
; and initial down pointer for ch 2
jc noteven ; this calculation is different if
; tap number is odd or even
jmp eeven
noteven add.w #0x1,R4 ; if not even number of coefficients
eeven mov.w R4,&COEFNO ; used for calculation is (N+1)
mov.w &(FILTER+2),R4 ; reload tap to calculate up and
; down pointer starting values
rla.w R4 ; X 2 for reserving up circular buffer
calc_pdn mov.w R4,R5 ; save result
rla.w R5 ; additional X 2 buffers for down buffer
sub.w #0x2,R5 ;
add.w #SAMPBUF,R4 ; calculate up buffer top pointer
mov.w R4,&PUP_INIT ; store value in PUP_INIT
mov.w R4,&UP ; temp store in UP for DMA operation
add.w #SAMPBUF,R5 ; initialize forward and backward
; sample buffer pointers.
mov.w R5,&PDN_INIT ; store value in PDN_INIT
mov.w R5,&DN ; temp store in DN for DMA operation
mov.w #0x0,&INPUT ; clear input sample
;Once configured the DMA executes the FIR algorithm
DMA_setup mov.w #DMA2TSEL_1+DMA1TSEL_1+DMA0TSEL_1,&DMACTL0
; DMA Channels triggered by TACCIFG2
; channel 0 is coef table
mov.w #DMASRCINCR_3,&DMA0CTL ; Increment source address after transfer
mov.w #(FILTER+4),&DMA0SA ; Points the first filled zero coefficient
mov.w #MACS,&DMA0DA ; Hardware multiplier MACS operand
mov.w &COEFNO,&DMA0SZ ; Size of transfer number of coefficients
; channel 1 addresses and sends to multiplier the first half sample window
mov.w #DMASRCINCR_3,&DMA1CTL ; Increment source address after transfer
mov.w &COEFNO,&DMA1SZ ; Size of transfer number of coefficients
mov.w &PUP_INIT,&DMA1SA ; Upper half data table
mov.w #OP2,&DMA1DA ; Hardware multiplier operand 2
; channel 2 addresses and sends to multiplier the second half sample window
mov.w #DMASRCINCR_2,&DMA2CTL ; Decrement source address after transfer
mov.w &COEFNO,&DMA2SZ ; Size of transfer number of coefficients
mov.w &PDN_INIT, &DMA2SA ; Lower half data table
mov.w #OP2,&DMA2DA ; Hardware multiplier operand 2
; set up timerA for DMA channel trigger source
mov.w #0x0,&TACCR0 ; Start with CCR0 = 0, Trigger disable
mov.w #0x1,&TACCR2 ; compare point soon after counter starts.
mov.w #OUTMOD_3,&TACCTL2 ; To trigger DMA
mov.w #TASSEL1+MC0,&TACTL ;
; TimerB, sample rate, ADC and DAC conversion triggers
clr.w &TBCCR0 ; Clear TBCCR0
mov.w #TBSSEL1+MC0,&TBCTL ; up mode SMCLK
mov.w &FILTER,R4 ; get sample rate from table
sub.w #20,R4 ; for ADC and DAC trigger pulse generation
mov.w R4,&TBCCR2 ; compare value for TBCCR2
sub.w #15,R4 ;
mov.w R4,&TBCCR1 ; compare value for TBCCR1
mov.w #OUTMOD_7,&TBCCTL1 ; to trigger ADC12
mov.w #OUTMOD_3,&TBCCTL2 ; to trigger DACs
; ADC - this peripheral is currently not used in this code but will
; be used when input to FIR is an actual external analog signal.
mov.w #SHT1_0+SHT0_0+ADC12ON+REFON+REF2_5V,&ADC12CTL0
; REF is required for DACs
mov.w #SHS_3+ADC12DIV_0+ADC12SSEL_2+CONSEQ_0,&ADC12CTL1
mov.w #0x0,&ADC12IE ; Disable ADC12 Interrupts
; DACs - used to output both input and output of the FIR in this demo
clr.w &DAC12_0DAT ; Clear DAC0 data register
mov.w #DAC12AMP_7+DAC12LSEL_3+DAC12IR+DAC12DF+ENC,&DAC12_1CTL
mov.w #DAC12AMP_7+DAC12LSEL_3+DAC12IR+DAC12DF+ENC,&DAC12_0CTL
bis.w #DAC12CALON,&DAC12_1CTL
bis.w #DAC12CALON,&DAC12_0CTL ; Self calibrate DAC0 and DAC1
; Initialize input sine wave frequency parameters for software frequency sweep
clr.w &BASE ; Clear the base frequency
mov.w #(2*FREQMIN), &FREQINC ; Start frequency
SetupFIR mov.w &FILTER,&TBCCR0 ; passed from filter table
bis.w #CCIE,&TBCCTL0 ; start timerB
bis.w #GIE,SR ; enable global interrupt
bis.w #DMAEN,&DMA0CTL ; enable DMA0
bis.w #DMAEN,&DMA1CTL ; enable DMA1
bis.w #DMAEN,&DMA2CTL ; enable DMA2
mov.w #TMAPER,&TACCR0 ; start FIR, by starting
; trigger of DMA channels
mov.w &FILTER,&TBCCR0 ; start TimerB and enable
; ADC and DAC
;-------------------------------------------------------------------------------
Userprogram
jmp Userprogram ; USer program, TimerA and DMA
; interrupt to execute the FIR
;-------------------------------------------------------------------------------
; TimerB Interrupt Service Routine
;-------------------------------------------------------------------------------
Timer_B0_ISR
mov.w &RESHI,&DAC12_1DAT ; move FIR filter output to DAC1
mov.w #0x0,&TACCR0 ; Stop DMA by stopping trigger
bic.w #CCIFG,&TACCTL2 ; Clear TimerA IFG
clr.w &RESLO ; Clear multiplier registers
clr.w &RESHI ; for next FIR run
mov.w #DMASRCINCR_3+DMAEN,&DMA0CTL;
mov.w #DMASRCINCR_3+DMAEN,&DMA1CTL;
mov.w #DMASRCINCR_2+DMAEN,&DMA2CTL; Reenable DMA channels and start
mov.w #TMAPER,&TACCR0 ; set Timer_A period for next run
sub.w #0x2,&UP ; update pointers for FIR
cmp.w #SAMPBUF,&UP ; check if top of up buffer reached
jz datamov ; if so reassign
mov.w &UP,R4 ; pointer for up circular buffer
mov.w &INPUT,0(R4) ; store input sample in circular buffer
mov.w &DN,R4 ; pointer for down circular buffer
mov.w &INPUT,0(R4) ; Back fill double buffer for data move
sub.w #0x2,&DN ; update pointer for FIR
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -