/********************************************************** * * lab13.c * * EE 477 Spring 2004 R.C. Maher * * Based on bp.c * Copyright (c) 2001 Analog Devices, Inc. * **********************************************************/ /* ADSP-2106x System Register bit definitions */ #include #include <21060.h> #include #include #include #include #include /* DMA Chain pointer bit definitions */ #define CP_PCI 0x20000 /* Program-Controlled Interrupts bit */ #define CP_MAF 0x1ffff /* Valid memory address field bits */ #define SetIOP(addr, val) (* (volatile int *) addr) = (val) #define GetIOP(addr) (* (volatile int *) addr) /**********************************************************/ #define NUM_TAPS 10 float pm coeffs[NUM_TAPS] = { #include "fir.h" }; float dm state[NUM_TAPS+1]; /**********************************************************/ #define SZ_regs_1847 16 int regs_1847[SZ_regs_1847] = { /* Note that the MCE bit is maintained throughout initial programming to hold off premature autocalibration. */ 0xc007, /* index 0 - left input control RCM WAS 0xc000 */ 0xc107, /* index 1 - right input control RCM WAS 0xc100 */ 0xc280, /* index 2 - left aux 1 input control */ 0xc380, /* index 3 - right aux 1 input control */ 0xc480, /* index 4 - left aux 2 input control */ 0xc580, /* index 5 - right aux 2 input control */ 0xc600, /* index 6 - left dac control */ 0xc700, /* index 7 - right dac control */ 0xc85C, /* index 8 - data format RCM WAS 0xc850 */ 0xc909, /* index 9 - interface configuration */ 0xca00, /* index 10 - pin control */ 0xcb00, /* index 11 - no register */ 0xcc40, /* index 12 - miscellaneous information */ 0xcd00, /* index 13 - digital mix control */ 0xce00, /* index 14 - no register */ 0x8f00}; /* index 15 - no register */ unsigned rx_buf[3]; /* receive buffer */ unsigned tx_buf[3] = {0xcc40, 0, 0}; /* transmit buffer */ /* DMA chaining Transfer Control Blocks */ typedef struct { unsigned lpath3; /* for mesh mulitprocessing */ unsigned lpath2; /* for mesh multiprocessing */ unsigned lpath1; /* for mesh multiprocessing */ unsigned db; /* General purpose register */ unsigned gp; /* General purpose register */ unsigned** cp; /* Chain Pointer to next TCB */ unsigned c; /* Count register */ unsigned im; /* Index modifier register */ unsigned * ii; /* Index register */ } _tcb; _tcb rx_tcb = {0, 0, 0, 0, 0, 0, 3, 1, 0}; /* receive tcb */ _tcb tx_tcb = {0, 0, 0, 0, 0, 0, 3, 1, 0}; /* transmit tcb */ int cmd_blk[8]; /* command block */ static int xmit_count; static int * xmit_ptr; static int source; static int filter; /**********************************************************/ /* */ /* Periodic timer interrupt */ /* */ /**********************************************************/ void timer_lo_prior( int sig_num ) { sig_num=sig_num; // Toggle flag 2 LED. set_flag(SET_FLAG2, TGL_FLAG); } /**********************************************************/ /* */ /* Serial port transmit DMA complete */ /* */ /**********************************************************/ void spt0_asserted( int sig_num ) { // Check if there are more commands left to transmit. if( xmit_count ) { // If so, put the command into the transmit buffer and update count. tx_buf[0] = *xmit_ptr++; xmit_count--; } } /**********************************************************/ /* */ /* Serial port receive DMA complete */ /* */ /* Sample processing code goes here! */ /* */ /**********************************************************/ void spr0_asserted( int sig_num ) { float filter_input,filter_output; int i; /* On entry to this function, */ /* rx_buf[1] is left channel input sample */ filter_input = (int) rx_buf[1]; /* Just pass the input to the output */ /* (your FIR will replace next line) */ filter_output = filter_input; //Make left and right outputs the same ( left: tx_buf[1], right: tx_buf[2] ) tx_buf[1]= (int)filter_output; tx_buf[2]= tx_buf[1]; } /**********************************************************/ /* */ /* */ /* */ /**********************************************************/ void setup_sports ( void ) { /* Configure SHARC serial port SPORT0 */ /* Multichannel communications setup */ sport0_iop.mtcs = 0x00070007; /* transmit on words 0,1,2,16,17,18 */ sport0_iop.mrcs = 0x00070007; /* receive on words 0,1,2,16,17,18 */ sport0_iop.mtccs = 0x00000000; /* no companding on transmit */ sport0_iop.mrccs = 0x00000000; /* no companding on receive */ /* TRANSMIT CONTROL REGISTER */ /* STCTL0 <= 0x001c00f2 */ /* An alternate (and more efficient) way of doing this would be to */ /* write the 32-bit register all at once with a statement like this: */ /* SetIOP(STCTL0, 0x001c00f2); */ /* But the following is more descriptive... */ sport0_iop.txc.mfd = 1; /* multichannel frame delay (MFD) */ sport0_iop.txc.schen = 1; /* Tx DMA chaining enable */ sport0_iop.txc.sden = 1; /* Tx DMA enable */ sport0_iop.txc.lafs = 0; /* Late TFS (alternate) */ sport0_iop.txc.ltfs = 0; /* Active low TFS */ sport0_iop.txc.ditfs = 0; /* Data independent TFS */ sport0_iop.txc.itfs = 0; /* Internally generated TFS */ sport0_iop.txc.tfsr = 0; /* TFS Required */ sport0_iop.txc.ckre = 0; /* Data and FS on clock rising edge */ sport0_iop.txc.gclk = 0; /* Enable clock only during transmission*/ sport0_iop.txc.iclk = 0; /* Internally generated Tx clock */ sport0_iop.txc.pack = 0; /* Unpack 32b words into two 16b tx's */ sport0_iop.txc.slen = 15; /* Data word length minus one */ sport0_iop.txc.sendn = 0; /* Data word endian 1 = LSB first */ sport0_iop.txc.dtype = SPORT_DTYPE_RIGHT_JUSTIFY_SIGN_EXTEND; /* Data type specifier */ sport0_iop.txc.spen = 0; /* Enable (clear for MC operation) */ /* RECEIVE CONTROL REGISTER */ /* SRCTL0 <= 0x1f8c20f2 */ sport0_iop.rxc.nch = 31; /* multichannel number of channels - 1 */ sport0_iop.rxc.mce = 1; /* multichannel enable */ sport0_iop.rxc.spl = 0; /* Loop back configure (test) */ sport0_iop.rxc.d2dma = 0; /* Enable 2-dimensional DMA array */ sport0_iop.rxc.schen = 1; /* Rx DMA chaining enable */ sport0_iop.rxc.sden = 1; /* Rx DMA enable */ sport0_iop.rxc.lafs = 0; /* Late RFS (alternate) */ sport0_iop.rxc.ltfs = 0; /* Active low RFS */ sport0_iop.rxc.irfs = 0; /* Internally generated RFS */ sport0_iop.rxc.rfsr = 1; /* RFS Required */ sport0_iop.rxc.ckre = 0; /* Data and FS on clock rising edge */ sport0_iop.rxc.gclk = 0; /* Enable clock only during transmission*/ sport0_iop.rxc.iclk = 0; /* Internally generated Rx clock */ sport0_iop.rxc.pack = 0; /* Pack two 16b rx's into 32b word */ sport0_iop.rxc.slen = 15; /* Data word length minus one */ sport0_iop.rxc.sendn = 0; /* Data word endian 1 = LSB first */ sport0_iop.rxc.dtype = SPORT_DTYPE_RIGHT_JUSTIFY_SIGN_EXTEND; /* Data type specifier */ sport0_iop.rxc.spen = 0; /* Enable (clear for MC operation) */ /* Enable sport0 xmit & rcv irqs (DMA enabled) */ interrupt(SIG_SPR0I, spr0_asserted); interrupt(SIG_SPT0I, spt0_asserted); /* Set up Transmit Transfer Control Block for chained DMA */ tx_tcb.ii = tx_buf; /* DMA source buffer address */ tx_tcb.cp = &tx_tcb.ii; /* define ptr to next TCB (point to self) */ SetIOP(CP2, (((int)&tx_tcb.ii) & CP_MAF) | CP_PCI); /* define ptr to current TCB (kick off DMA) */ /* (SPORT0 transmit uses DMA ch 2) */ /* Set up Receive Transfer Control Block for chained DMA */ rx_tcb.ii = rx_buf; /* DMA destination buffer address */ rx_tcb.cp = &rx_tcb.ii; /* define ptr to next TCB (point to self) */ SetIOP(CP0, (((int)&rx_tcb.ii) & CP_MAF) | CP_PCI); /* define ptr to current TCB (kick off DMA) */ /* (SPORT0 receive uses DMA ch 0) */ } /**********************************************************/ /* */ /* */ /* */ /**********************************************************/ void send_1847_config_cmds( void ) { // Set up pointer and counter to transmit commands. xmit_ptr = regs_1847; xmit_count = SZ_regs_1847; // Wait for all commands to be transmitted. while( xmit_count ) idle(); // Wait for AD1847 autocal to start. while( !(rx_buf[0] & 0x0002) ) idle(); // Wait for AD1847 autocal to finish. while( rx_buf[0] & 0x0002 ) idle(); return; } /**********************************************************/ /* */ /* */ /* */ /**********************************************************/ void init_21k( void ) { // Disable timer and set rate to 4 Hz. timer_off(); timer_set( 10000000, 10000000 ); // Initialize pointer and counter to transmit commands. xmit_count = 0; xmit_ptr = regs_1847; // Enable interrupt nesting. asm( "#include " ); asm( "bit set mode1 NESTM;" ); // Enable timer (low priority) interrupt. interrupt( SIG_TMZ, timer_lo_prior ); // Turn flag LEDs off. set_flag( SET_FLAG2, SET_FLAG ); return; } /**********************************************************/ /* */ /* */ /* */ /**********************************************************/ void main ( void ) { int i; int x; // Initialize state array for FIR filter. for( i=0 ; i