;***************************************************************************** ; Sampler.s ; dsPIC-based Sample/Playback for dsPICDEM board ; CTEC1631, Niagara College, Canada (Professor M. Csele) ; ; Other Files Required : p30F6012.gld, p30f6012.inc ; Tools Used : MPLAB IDE : 7.5x ; ; Hardware: ; dsPICDEM board standard hardware ; Line IN provided via AN3/RB3 ; Line OUT provided via MCP4101 ; Indicator LEDs on RD4-RD7 ; ; Revision History ; 1.0 2005/05/17 First version, ported from dsPICDEM 1.1 version ; 1.1 2007/11/12 Fixed sampling rate for 4MHz XTAL ; ;***************************************************************************** .equ __30F6012, 1 .include "p30f6012.inc" ;............................................................................. ; Configuration bits: ;............................................................................. ;Set processor speed here - CAREFUL since the selection affects sampling rate config __FOSC, CSW_FSCM_OFF & XT_PLL16 ;16xPLL - 64MHz/16MIPs at 4MHz XTAL ; config __FOSC, CSW_FSCM_OFF & XT_PLL4 ;4xPLL ; config __FOSC, CSW_FSCM_OFF & XT config __FWDT, WDT_OFF ;Turn off Watchdog Timer config __FBORPOR, PBOR_ON & BORV_27 & PWRT_16 & MCLR_EN ;Set Brown-out Reset voltage and config __FGS, CODE_PROT_OFF ;Set Code Protection Off ;............................................................................. ; Global Declarations: ;............................................................................. .global __reset ;Label for first line of code. .global __ICD2RAM ;Allows ICD2 to be used ;............................................................................. ; Variable Storage in Data space (beginning at 0x850) ;............................................................................. .section .data .align 2 DelayReg: .space 2 ;Test Variable SampleN: .space 2 ; x[n] SampleN_1: .space 2 ; x[n-1] SampleN_2: .space 2 ; x[n-2] SampleN_3: .space 2 ; x[n-3] SampleN_4: .space 2 ; x[n-4] SampleN_5: .space 2 ; x[n-5] SampleN_6: .space 2 ; x[n-6] SampleN_7: .space 2 ; x[n-7] SampleN_8: .space 2 ; x[n-8] SampleN_9: .space 2 ; x[n-9] SampleN_10: .space 2 ; x[n-10] ;Declare all required variables here NumPoints: .space 2 ; Number of points in moving average ;............................................................................. ; Constants stored in Program space ;............................................................................. .equ SS,#9 ;RG9 = Slave Select for MCP .equiv FCY, 1000000 ;Instruction Cycle Frequency (4MHz/4) .equiv DelayConst, FCY/2000 ;............................................................................. ; Code Section in Program Memory ;............................................................................. .text ;Start of Code section __reset: mov #__SPLIM_init-#128, W15 ;Initialize the Stack Pointer to base address mov #__SPLIM_init, W0 ;Initialize the Stack Pointer Limit Register mov W0, SPLIM nop bset CORCON,#IF ;Select Integer mode for DSP Multiplier ;Setup Ports mov #0xFF0F,W0 ;RD4-7=LED Outputs mov W0,TRISD mov #0xFFFF,W0 ;Port B all inputs mov W0,TRISB clr PORTG bset PORTG,#SS ;set SPI slave select high bclr TRISG,#SS ;set tris bit to output ;Setup hardware to allow ADC conversion on AN2-AN7 mov #0B1111111111110011,W0 ;RB3 = analog input mov W0,ADPCFG mov #0B0000000011100000,W0 ;Set for Auto Sampling (SSRC=111) mov W0,ADCON1 mov #0x0003,W0 ;Connect RB3/AN3 as CH0 input .. mov W0,ADCHS clr ADCSSL mov #0B0000000100111001,W0 ;Auto Sample, Tad for 30 MIPs max mov W0,ADCON3 clr ADCON2 ;AVdd,AVss external references on the 6011 chip bset ADCON1,#ADON ;Turn ADC ON bset ADCON1,#SAMP ; start sampling ... ;Setup Timer 1 for sampling delay mov #0x8000,w1 mov w1,T1CON ;1:1, Int Clk, ON mov #2000,W1 ;Load PR1 for delay, 8KS/s Sample Rate @4MHz/*16 PLL mov w1,PR1 ;Setup the SPI port 2 for the MCP chip mov #0x053B,w0 ;Master mode, 16 bits,no frame, 1:2 prescale mov w0,SPI2CON clr SPI2STAT bset SPI2STAT,#SPIEN ;Enable SPI2 bset PORTD,#4 ;Light LED 4 to show 'READY' MainLoop: call SampleIn ;Read a sample from the ADC (12-bits resolution) ;Filter code goes here ... current sample x[n] is in w0 mov w0, SampleN mov #3, NumPoints mov NumPoints, w1 ; Size of moving average filter in w1 dec w1, w1 ; Number of shifts is size of filter - 1 mov #SampleN_2, w2 ; address of SampleN_2 -> w2 [pointer] mov #SampleN_1, w3 ; address of SampleN_1 -> w3 [pointer] repeat w1 mov [w3--], [w2--] ; shift previous samples mov w0, SampleN ; store current sample mov #SampleN, w8 ; set up w8 to point to start of sample array (x[0]) mov #1, w4 ; multiply by 1 in MAC clr a, [w8] += 2, w5 ; clear accumulator a and set up prefetch ; for 16-bit samples repeat NumPoints ; loop over entire sample array mac w4*w5, a, [w8] += 2, w5 ; multiply current sample by 1 and sum into accumulator a ; continue prefetching mov ACCAH, w3 ; Result of sum is potentially 18 bits ; (20 bits for 11-point) mov ACCAL, w2 ; 32-bit dividend mov NumPoints, w4 ; 16-bit divisor repeat #17 div.sd w2, w4 ; Divide sum by N; Average is in w0 ;Filter code ends here ... put current output y[n] into w0 rrnc w0,w0 ;Shift right 4 bits (lower byte=data) rrnc w0,w0 rrnc w0,w0 rrnc w0,w0 mov #0x00FF,w1 ;Set upper byte to zero and w0,w1,w0 mov #0x1300,w1 ;Set upper byte to "0x13" add w0,w1,w0 call SampleOut ;Output w0 via the MCP DAC (8-bits resolution) call SamplingDelay goto MainLoop ;****** Sample Incoming Audio Signal to w0 ****** SampleIn: bset ADCON1,#SAMP ;Start sampling, conversion is auto WaitForADCDone: btss IFS0,#ADIF ;conversion done? goto WaitForADCDone ; if not, wait for it bclr IFS0,#ADIF ;Reset conversion flag mov ADCBUF0,w0 ;Read current ADC value return ;****** Playback Sample in w0 via the MCP ****** SampleOut: bclr IFS1,#SPI2IF ;clear the SPI2 interrupt flag DummyRead: mov SPI2BUF,w1 ;dummy read SPI2 buffer btsc SPI2STAT,#SPIRBF ;if spi buffer is full then bra DummyRead ; ... keep reading bclr PORTG,#SS ;start spi write mov w0,SPI2BUF ;load spi buffer TxDone: btss IFS1,#SPI2IF ;if flag is set then Tx is done bra TxDone ;else wait till it is done bset PORTG,#SS ;stop spi return ;***** Wait for timer to expire, start next delay ***** SamplingDelay: btss IFS0,#T1IF ;Wait for Timer to expire bra SamplingDelay bclr IFS0,#T1IF ;Clear 'done' flag return ;--------End of All Code Sections-------------------------------------------- .end ;End of program code in this file