/* * Helper function to write aic23 registers */ static void set_aic23_register(MCBSP_Handle hMcbsp, Uint16 reg, Uint16 val) { val &= 0x1ff; //LOG_printf(&LOG0, "Transmit data: %d", (reg<<9) | val); while(!MCBSP_xrdy(hMcbsp)); MCBSP_write(hMcbsp, (reg<<9) | val); while (MCBSP_xrdy(hMcbsp)); }
void codec_reg_set(uint16_t num, uint16_t val) { val &= 0x1ff; while(!MCBSP_xrdy(mcbspControlHandle)); MCBSP_write(mcbspControlHandle, (num << 9) | val); while(!MCBSP_xrdy(mcbspControlHandle)); }
interrupt void serialPortRcvISR() { union {Uint32 combo; short channel[2];} temp; int out = 0; temp.combo = MCBSP_read(DSK6713_AIC23_DATAHANDLE); // Note that right channel is in temp.channel[0] // Note that left channel is in temp.channel[1] //create temporary variable of left channel for processing short tempF = temp.channel[1]; //scale up input value to Q-26 int tempScaled = tempF << 11; int i; out = tempScaled; //reset the cyclical buffer sub-index if(n >= 3){ n = 0; } //calculate the output of each second order section and pass it to the next for(i = 0; i < 11; i++) { out = lordBiquad(out, i); } n++; //downscale the output back to Q-15 and cast as a short before writing to the codec temp.channel[0] = (short)(out >> 11); MCBSP_write(DSK6713_AIC23_DATAHANDLE, temp.combo); }
main() { LOG_printf(&myLog, "main begin"); /*DSK6713_LED_toggle(0); DSK6713_LED_toggle(1); DSK6713_LED_toggle(2); DSK6713_LED_toggle(3);*/ hMcbsp = 0; CSL_init(); /* Configure McBSP0 and AIC23 */ Config_DSK6713_AIC23(); /* Configure McBSP1*/ hMcbsp = MCBSP_open(MCBSP_DEV1, MCBSP_OPEN_RESET); MCBSP_config(hMcbsp, &datainterface_config); /* configure EDMA */ config_EDMA(); /* finally the interrupts */ config_interrupts(); //MCBSP_start(hMcbsp, RRST, 0xffffffff); // EIGEN!!!: Start Field: Recieve MCBSP_start(hMcbsp, MCBSP_RCV_START | MCBSP_XMIT_START | MCBSP_SRGR_START | MCBSP_SRGR_FRAMESYNC, 220); // EIGEN!!!: Start Field: Recieve // Es gibt auch noch MCBSP_SRGR_START (start sample Rate Generator) und MCBSP_SRGR_FRAMESYNC (start frame sync. generation) MCBSP_write(hMcbsp, 0x0); /* one shot */ LOG_printf(&myLog, "main end"); //DSK6713_LED_toggle(2); } /* finished*/
// for out to Left and Right channels void output_sample(int out_data) { short CHANNEL_data; // clear data structure AIC_data.uint=0; // 32-bit data -->data structure AIC_data.uint=out_data; /******************************************************************************** * The existing interface defaults to right channel. To default instead to the * left channel and use output_sample(short), left and right channels are swapped * In main source program use LEFT 0 and RIGHT 1 (opposite of what is used here) ********************************************************************************/ // swap left and right channels CHANNEL_data=AIC_data.channel[RIGHT]; AIC_data.channel[RIGHT]=AIC_data.channel[LEFT]; AIC_data.channel[LEFT]=CHANNEL_data; // if ready to transmit if (poll) while(!MCBSP_xrdy(DSK6713_AIC23_DATAHANDLE)); // write/output data MCBSP_write(DSK6713_AIC23_DATAHANDLE,AIC_data.uint); }
main() { CSL_init(); /* Configure McBSP0 and AIC23 */ Config_DSK6713_AIC23(); /* Configure McBSP1*/ hMcbsp = MCBSP_open(MCBSP_DEV1, MCBSP_OPEN_RESET); MCBSP_config(hMcbsp, &datainterface_config); /* configure EDMA */ config_EDMA(); DSK6713_LED_off(0); DSK6713_LED_on(1); DSK6713_LED_off(2); DSK6713_LED_on(3); /* finally the interrupts */ config_interrupts(); MCBSP_start(hMcbsp, MCBSP_XMIT_START | MCBSP_RCV_START, 0xffffffff); // Start Audio IN & OUT transmision MCBSP_write(hMcbsp, 0x0); /* one shot */ configComplete = 1; //t_reg = DSK6713_rget(DSK6713_MISC); //t_reg |= MCBSP1SEL; // Set MCBSP1SEL to 1 (extern) //DSK6713_rset(DSK6713_MISC,t_reg); } /* finished*/
interrupt void serialPortRcvISR() { union {Uint32 combo; short channel[2];} temp; int out = 0; temp.combo = MCBSP_read(DSK6713_AIC23_DATAHANDLE); // Note that right channel is in temp.channel[0] // Note that left channel is in temp.channel[1] //create temporary variable of left channel for processing short tempIn = temp.channel[1]; //Shift input signal to a Q-26 number int tempScaled = tempIn << 11; //initialize storage variable for calculating intermediate values //sum will be a Q-26 number int sum = 0; //loop variables int k, i; //reset cyclical buffer index if(n >= 11) { n = 0; } //calculate intermediate values //iterate to sum the last 18 intermediate values*A_coefficients for(k = 1; k<L; k++){ i = n - k; if(i < 0){ i += L; } //coefficients are Q-12 and intermediate values are Q-14 resulting in adding Q-26 numbers to sum sum += ((DEN[k])*(w[i])); } //subtract sum(Q-26) from the current scaled reading(Q-26) and scale down to Q-14 to store as an intermediate value w[n] = (tempScaled - sum) >> 12; //iterate to sum the current and last 18 intermediate values*B_coefficients for(k=0;k<L;k++){ i = n - k; if(i < 0){ i += L; } //scale down intermediate values to avoid output overflow out += (NUM[k]*(w[i] >> 10)); } n++; //scale down the output and cast as a short before writing to the codec temp.channel[0] = (short)(out >> 8); MCBSP_write(DSK6713_AIC23_DATAHANDLE, temp.combo); }
interrupt void serialPortRcvISR() { union {Uint32 combo; short channel[2];} temp; float out = 0; temp.combo = MCBSP_read(DSK6713_AIC23_DATAHANDLE); // Note that right channel is in temp.channel[0] // Note that left channel is in temp.channel[1] //create temporary variable of left channel for processing float tempF = temp.channel[1]; float sum = 0; //perform scaling => [-1, 1) tempF /= 32768; int k, i; if(n >= 11) { n = 0; } //calculate intermediate values //iterate to sum the last 18 intermediate values*A_coefficients for(k = 1; k<L; k++){ i = n - k; if(i < 0){ i += L; } sum += DEN[k]*w[i]; } //subtract sum from the current scaled reading w[n] = tempF - sum; if(w[n] > maxIntermediate){ maxIntermediate = w[n]; } if(w[n] < maxMin){ maxMin = w[n]; } //iterate to sum the current and last 18 intermediate values*B_coefficients for(k=0;k<L;k++){ i = n - k; if(i < 0){ i += L; } out += NUM[k] * w[i]; } n++; //rescale and output out *= 32768; temp.channel[0] = (short)out; MCBSP_write(DSK6713_AIC23_DATAHANDLE, temp.combo); }
/* * initEdma() - Initialize the DMA controller. Use linked transfers to * automatically transition from ping to pong and visa-versa. */ void initEdma(void) { /* Configure transmit channel */ hEdmaXmt = EDMA_open(EDMA_CHA_XEVT1, EDMA_OPEN_RESET); // get hEdmaXmt handle and reset channel hEdmaReloadXmtPing = EDMA_allocTable(-1); // get hEdmaReloadXmtPing handle hEdmaReloadXmtPong = EDMA_allocTable(-1); // get hEdmaReloadXmtPong handle gEdmaConfigXmt.dst = MCBSP_getXmtAddr(hMcbsp1); // set the desination address to McBSP1 DXR gXmtChan = EDMA_intAlloc(-1); // get an open TCC gEdmaConfigXmt.opt |= EDMA_FMK(OPT,TCC,gXmtChan); // set TCC to gXmtChan EDMA_config(hEdmaXmt, &gEdmaConfigXmt); // then configure the registers EDMA_config(hEdmaReloadXmtPing, &gEdmaConfigXmt); // and the reload for Ping gEdmaConfigXmt.src = EDMA_SRC_OF(gBufferXmtPong); // change the structure to have a source of Pong EDMA_config(hEdmaReloadXmtPong, &gEdmaConfigXmt); // and configure the reload for Pong EDMA_link(hEdmaXmt,hEdmaReloadXmtPong); // link the regs to Pong EDMA_link(hEdmaReloadXmtPong,hEdmaReloadXmtPing); // link Pong to Ping EDMA_link(hEdmaReloadXmtPing,hEdmaReloadXmtPong); // and link Ping to Pong /* Configure receive channel */ hEdmaRcv = EDMA_open(EDMA_CHA_REVT1, EDMA_OPEN_RESET); // get hEdmaRcv handle and reset channel hEdmaReloadRcvPing = EDMA_allocTable(-1); // get hEdmaReloadRcvPing handle hEdmaReloadRcvPong = EDMA_allocTable(-1); // get hEdmaReloadRcvPong handle gEdmaConfigRcv.src = MCBSP_getRcvAddr(hMcbsp1); // and the desination address to McBSP1 DXR gRcvChan = EDMA_intAlloc(-1); // get an open TCC gEdmaConfigRcv.opt |= EDMA_FMK(OPT,TCC,gRcvChan); // set TCC to gRcvChan EDMA_config(hEdmaRcv, &gEdmaConfigRcv); // then configure the registers EDMA_config(hEdmaReloadRcvPing, &gEdmaConfigRcv); // and the reload for Ping gEdmaConfigRcv.dst = EDMA_DST_OF(gBufferRcvPong); // change the structure to have a destination of Pong EDMA_config(hEdmaReloadRcvPong, &gEdmaConfigRcv); // and configure the reload for Pong EDMA_link(hEdmaRcv,hEdmaReloadRcvPong); // link the regs to Pong EDMA_link(hEdmaReloadRcvPong,hEdmaReloadRcvPing); // link Pong to Ping EDMA_link(hEdmaReloadRcvPing,hEdmaReloadRcvPong); // and link Ping to Pong /* Enable interrupts in the EDMA controller */ EDMA_intClear(gXmtChan); EDMA_intClear(gRcvChan); // clear any possible spurious interrupts EDMA_intEnable(gXmtChan); // enable EDMA interrupts (CIER) EDMA_intEnable(gRcvChan); // enable EDMA interrupts (CIER) EDMA_enableChannel(hEdmaXmt); // enable EDMA channel EDMA_enableChannel(hEdmaRcv); // enable EDMA channel /* Do a dummy write to generate the first McBSP transmit event */ MCBSP_write(hMcbsp1, 0); }
void sendData(uint32_t * ptr) { while(!MCBSP_rrdy(mcbspDataHandle)); MCBSP_write(mcbspDataHandle, *ptr); asm(" nop"); asm(" nop"); asm(" nop"); asm(" nop"); asm(" nop"); asm(" nop"); }
unsigned char spiTransferByte(unsigned char arg_byte) { unsigned char i; MCBSP_write(C55XX_SPI_hMcbsp, arg_byte); while (!MCBSP_xrdy(C55XX_SPI_hMcbsp)); i = MCBSP_read(C55XX_SPI_hMcbsp); #if 0 if (arg_byte == 0 && i == 0) hpprintf ("*"); else hpprintf("(%x)=%x\n", arg_byte, i); #endif return i; }
//for output from right channel void output_right_sample(short out_data) { // clear data structure AIC_data.uint=0; // data from Right channel -->data structure AIC_data.channel[RIGHT]=out_data; // if ready to transmit if (poll) while(!MCBSP_xrdy(DSK6713_AIC23_DATAHANDLE)); // output right channel MCBSP_write(DSK6713_AIC23_DATAHANDLE,AIC_data.uint); }
unsigned char if_spiSend(hwInterface *iface, euint8 outgoing) { unsigned char r; /* while((*(unsigned volatile long*)McBSP0_SPCR & 0x20000)==0); *(unsigned volatile char*)McBSP0_DXR=outgoing; while(((*(unsigned volatile long*)McBSP0_SPCR & 0x2)==0)); r=*(unsigned volatile char*)McBSP0_DRR; */ while(!MCBSP_xrdy(iface->port->hBsp)); MCBSP_write(iface->port->hBsp,outgoing); while(!MCBSP_rrdy(iface->port->hBsp)); r=MCBSP_read(iface->port->hBsp); return(r); }
static void set_aic23_register(MCBSP_Handle hMcbsp,unsigned short regnum, unsigned short regval) { /* Programmierung erfolgt so, dass in B[15:9] die Registernummer steht und in B[8:0] die zu schreibenden Daten */ /* zur Sicherheit maskieren auf 9 Bit */ regval &= 0x1ff; //regnum &= 0x07f; /* warten */ while (!MCBSP_xrdy(hMcbsp)); /* schreiben */ MCBSP_write(hMcbsp, (regnum << 9) | regval); }
interrupt void serialPortRcvISR() { union {Uint32 combo; short channel[2];} temp; int out = 0; temp.combo = MCBSP_read(DSK6713_AIC23_DATAHANDLE); // Note that right channel is in temp.channel[0] // Note that left channel is in temp.channel[1] //create temporary variable of left channel for processing short tempF = temp.channel[1]; int sum = 0; int k, i; if(n >= 11) { n = 0; } //iterate to sum the last 18 intermediate values*A_coefficients for(k = 1; k<L; k++){ i = n - k; if(i < 0){ i += L; } sum += DEN[k]*w[i]; } //subtract sum from the current scaled reading w[n] = tempF - sum; //iterate to sum the current and last 18 intermediate values*B_coefficients for(k=0;k<L;k++){ i = n - k; if(i < 0){ i += L; } out += NUM[k] * w[i]; } n++; temp.channel[0] = (short)out; MCBSP_write(DSK6713_AIC23_DATAHANDLE, temp.combo); }
interrupt void serialPortRcvISR() { union {Uint32 combo; short channel[2];} temp; float out = 0; temp.combo = MCBSP_read(DSK6713_AIC23_DATAHANDLE); // Note that right channel is in temp.channel[0] // Note that left channel is in temp.channel[1] //temp.channel[1] = temp.channel[0]; //create temporary variable of left channel for processing float tempF = temp.channel[1]; //perform scaling => [-1, 1) tempF /= 32768; //wait for buffer to fill up with samples before filtering //buffer is full, now perform filter int i,j; if(n >= ORDER) { n = 0; } x[n] = tempF; //Calculate filter gain for(i = 0; i < ORDER; i++){ j = n - i; if(j < 0){ j += ORDER; } out += B[i] * x[j]; } n++; //rescale and output out *= 32768; temp.channel[0] = (short)out; MCBSP_write(DSK6713_AIC23_DATAHANDLE, temp.combo); }
interrupt void serialPortRcvISR() { union {Uint32 combo; short channel[2];} temp; temp.combo = MCBSP_read(DSK6713_AIC23_DATAHANDLE); // Note that right channel is in temp.channel[0] // Note that left channel is in temp.channel[1] if(pingFlag == 1 && lflag == 1) { PONG[pongIndex].re = temp.channel[1]; PONG[pongIndex].re /= 32768; PONG[pongIndex].im = 0; temp.channel[0] = (short)outputPING[pongIndex]; pongIndex++; if(pongIndex >= FFT_LENGTH - (ORDER - 1)) { pongFlag = 1; pongIndex = 0; pingFlag = 0; } } if(pongFlag == 1 && lflag == 1) { PING[pingIndex].re = temp.channel[1]; PING[pingIndex].re /= 32768; PING[pingIndex].im = 0; temp.channel[0] = (short)outputPONG[pingIndex]; pingIndex++; if(pingIndex >= FFT_LENGTH - (ORDER - 1)) { pingFlag = 1; pingIndex = 0; pongFlag = 0; } } MCBSP_write(DSK6713_AIC23_DATAHANDLE, temp.combo); }
void DSK6713_configure_AIC23() { /* Configure McBSP0 as control interface for aic23 */ MCBSP_Handle MCBSP0_handle; MCBSP0_handle = MCBSP_open(MCBSP_DEV0, MCBSP_OPEN_RESET); MCBSP_config(MCBSP0_handle, &MCBSP0_config); MCBSP_start(MCBSP0_handle, MCBSP_XMIT_START | MCBSP_SRGR_START | MCBSP_SRGR_START, 220); set_aic23_register(MCBSP0_handle, RESET_REGISTER, 0x0000); set_aic23_register(MCBSP0_handle, POWER_DOWN_CONTROL, 0x0000); set_aic23_register(MCBSP0_handle, LEFT_LINE_INPUT_CHANNEL_VOLUME, 0x0017); set_aic23_register(MCBSP0_handle, RIGHT_LINE_INPUT_CHANNEL_VOLUME, 0x0017); set_aic23_register(MCBSP0_handle, LEFT_CHANNEL_HEADPHONE_VOLUME, 0x00f9); set_aic23_register(MCBSP0_handle, RIGHT_CHANNEL_HEADPHONE_VOLUME, 0x00f9); set_aic23_register(MCBSP0_handle, ANALOG_AUDIO_PATH, 0x0011); // 00001 0010 set_aic23_register(MCBSP0_handle, DIGITAL_AUDIO_PATH, 0x0000); // 000000000 set_aic23_register(MCBSP0_handle, DIGITAL_AUDIO_INTERFACE_FORMAT, 0x0043); //0 0100 0001 set_aic23_register(MCBSP0_handle, SAMPLE_RATE_CONTROL, 0x000d); // 01100 set_aic23_register(MCBSP0_handle, DIGITAL_INTERFACE_ACTIVATION, 0x0001); /* Configure McBSP1 as data interface for aic23 */ MCBSP_Handle MCBSP1_handle; MCBSP1_handle = MCBSP_open(MCBSP_DEV1, MCBSP_OPEN_RESET); MCBSP_config(MCBSP1_handle, &MCBSP1_config); MCBSP_start(MCBSP1_handle, MCBSP_XMIT_START|MCBSP_RCV_START|MCBSP_SRGR_FRAMESYNC|MCBSP_SRGR_START, 220); /* Configure receive EDMA */ EDMA_Handle hEdmaRcv; EDMA_Handle hEdmaRcvA; EDMA_Handle hEdmaRcvB; hEdmaRcv = EDMA_open(EDMA_CHA_REVT1, EDMA_OPEN_RESET); hEdmaRcvA = EDMA_allocTable(-1); hEdmaRcvB = EDMA_allocTable(-1); gEdmaRcvConfig.src = MCBSP_getRcvAddr(MCBSP1_handle); // Get address of DRR gTccRcvChan = EDMA_intAlloc(-1); // get next free transfer complete code gEdmaRcvConfig.opt |= EDMA_FMK(OPT, TCC, gTccRcvChan); EDMA_config(hEdmaRcv, &gEdmaRcvConfig); EDMA_config(hEdmaRcvA, &gEdmaRcvConfig); gEdmaRcvConfig.dst = EDMA_DST_OF(gRcvBufferB); EDMA_config(hEdmaRcvB, &gEdmaRcvConfig); EDMA_link(hEdmaRcv, hEdmaRcvB); EDMA_link(hEdmaRcvB, hEdmaRcvA); EDMA_link(hEdmaRcvA, hEdmaRcvB); /* Configure transmit EDMA */ EDMA_Handle hEdmaXmt; EDMA_Handle hEdmaXmtA; EDMA_Handle hEdmaXmtB; hEdmaXmt = EDMA_open(EDMA_CHA_XEVT1, EDMA_OPEN_RESET); hEdmaXmtA = EDMA_allocTable(-1); hEdmaXmtB = EDMA_allocTable(-1); gEdmaXmtConfig.dst = MCBSP_getXmtAddr(MCBSP1_handle); // Get address of DXR gTccXmtChan = EDMA_intAlloc(-1); // get next free transfer complete code gEdmaXmtConfig.opt |= EDMA_FMK(OPT, TCC, gTccXmtChan); EDMA_config(hEdmaXmt, &gEdmaXmtConfig); EDMA_config(hEdmaXmtA, &gEdmaXmtConfig); gEdmaXmtConfig.src = EDMA_DST_OF(gXmtBufferB); // set source to buffer B EDMA_config(hEdmaXmtB, &gEdmaXmtConfig); EDMA_link(hEdmaXmt, hEdmaXmtB); EDMA_link(hEdmaXmtB, hEdmaXmtA); EDMA_link(hEdmaXmtA, hEdmaXmtB); EDMA_intClear(gTccRcvChan); EDMA_intClear(gTccXmtChan); EDMA_intEnable(gTccRcvChan); EDMA_intEnable(gTccXmtChan); gBufferState.cpuBufferState = StateB; // inittial cpu buffer state EDMA_enableChannel(hEdmaRcv); EDMA_enableChannel(hEdmaXmt); IRQ_clear(IRQ_EVT_EDMAINT); IRQ_enable(IRQ_EVT_EDMAINT); MCBSP_write(MCBSP1_handle, 0x00); }
interrupt void serialPortRcvISR() { union {Uint32 combo; short channel[2];} temp; short ii=0; short jj=0; temp.combo = MCBSP_read(DSK6713_AIC23_DATAHANDLE); // Note that right channel is in temp.channel[0] // Note that left channel is in temp.channel[1] // keep track of largest sample for diagnostics if (temp.channel[0]>max_samp) max_samp = temp.channel[0]; if (state==0) { // SEARCHING STATE // put sample in searching buffer buf[bufindex] = (float) temp.channel[0]; // right channel // compute incoherent correlation zc = 0; zs = 0; for (ii=0;ii<M;ii++) { zc += mfc[ii]*buf[ii]; zs += mfs[ii]*buf[ii]; } zz = zc*zc+zs*zs; if (zz>T1) { // threshold exceeded? max_recbuf = 0; state = 1; // enter "recording" state (takes effect in next interrupt) DSK6713_LED_toggle(0); // toggle LED here for diagnostics // record time of first sample (DRB fixed 4/19/2015: added +1) recbuf_start_clock = sincpulsebuf_counter-M+1; // should not be negative since we started counting when we launched the S->M sinc pulse recbufindex = M; // start recording new samples at position M jj = bufindex; // for (ii=0;ii<M;ii++){ // copy samples from buf to first M elements of recbuf jj++; // the first time through, this puts us at the oldest sample if (jj>=M) jj=0; recbuf[ii] = buf[jj]; buf[jj] = 0; // clear out searching buffer to avoid false trigger } } else { // increment and wrap pointer bufindex++; if (bufindex>=M) bufindex = 0; } } else if (state==1) { // RECORDING STATE // put sample in recording buffer recbuf[recbufindex] = (float) temp.channel[0]; // right channel recbufindex++; if (recbufindex>=(2*N+2*M)) { state = 2; // buffer is full delay_est_done = 0; // clear flag DSK6713_LED_toggle(0); // toggle LED here for diagnostics recbufindex = 0; // shouldn't be necessary } } else if (state==2) { // CALCULATING DELAY ESTIMATES STATE if (delay_est_done==1) { // are the delay estimates done calculating? state = 3; // next state } } else if (state==3) { // WRITE ADJUSTED VIRTUAL CLOCK BUFFER STATE delay_est_done = 0; // clear flag state = 0; // xxx temporary } if (state==-1) { // WARMUP STATE (NO OUTPUT) if (sincpulsebuf_counter>LL/2) { state = 0; } temp.channel[1] = 0; temp.channel[0] = 0; } else { if (vclock_counter==buffer_swap_index) swap_pending = 1; if ((swap_pending==1)&&(state!=2)) // ok to swap buffer { swap_pending = 0; buffer_just_swapped = 1; if (current_clockbuf==0) current_clockbuf = 1; else current_clockbuf = 0; } temp.channel[1] = clockbuf_shifted[current_clockbuf][vclock_counter]; // slave *shifted* clock signal (always played) // temp.channel[1] = clockbuf[vclock_counter]; // slave *unshifted* clock signal (for debug) temp.channel[0] = sincpulsebuf[sincpulsebuf_counter]; // this initiates the sinc pulse exchange with the master } MCBSP_write(DSK6713_AIC23_DATAHANDLE, temp.combo); // output L/R channels // update virtual clock (cycles from 0 to L-1) vclock_counter++; if (vclock_counter>=L) { vclock_counter = 0; // clock tick occurred, wrap } // update sinc pulse counter (cycles from 0 to LL-1) // this is for sinc pulses from the slave to the master // sinc pulses from the slave to the master have their peak at // sincpulsebuf_counter = 0 (this makes clock offset calculations simple) sincpulsebuf_counter++; if (sincpulsebuf_counter>=LL) { sincpulsebuf_counter = 0; // wrap } }
void codec_reset() { while(!MCBSP_xrdy(mcbspControlHandle)); MCBSP_write(mcbspControlHandle, (15 << 9) | 0); while(!MCBSP_xrdy(mcbspControlHandle)); }
interrupt void serialPortRcvISR() { union {Uint32 combo; short channel[2];} temp; temp.combo = MCBSP_read(DSK6713_AIC23_DATAHANDLE); // Note that right channel is in temp.channel[0] // Note that left channel is in temp.channel[1] // keep track of largest sample for diagnostics if (temp.channel[0]>max_samp) max_samp = temp.channel[0]; if (state==STATE_SEARCH) { // SEARCHING STATE //search_for_thresh(&(temp.channel[0]),PASSTHROUGH); // isSearching++; // put sample in searching buffer ///* buf[bufindex] = (float) temp.channel[0]; // right channel if (PASSTHROUGH!=1) { temp.channel[0] = 0; // can comment this out for debugging at home } // compute incoherent correlation zc = 0; zs = 0; for(i=0;i<M;i++) { zc += mfc[i]*buf[i]; zs += mfs[i]*buf[i]; } z = zc*zc+zs*zs; if (z>T1) { // threshold exceeded? max_recbuf = 0; state = 1; // enter "recording" state (takes effect in next interrupt) recbufindex = M; // start recording new samples at position M j = bufindex; // for (i=0;i<M;i++){ // copy samples from buf to first M elements of recbuf j++; // the first time through, this puts us at the oldest sample if (j>=M) j=0; recbuf[i] = (short) buf[j]; buf[j] = 0; // clear out searching buffer to avoid false trigger } } else { // increment and wrap pointer bufindex++; if (bufindex>=M) bufindex = 0; } //*/ } else if (state==STATE_RECORD) { // RECORDING STATE //DEBUG if(!ledTriggered) { DSK6713_LED_toggle(0); ledTriggered = 1; } // put sample in recording buffer recbuf[recbufindex] = temp.channel[0]; // right channel if (PASSTHROUGH!=1) { temp.channel[0] = 0; // can comment this out for debugging at home } if (abs(recbuf[recbufindex])>max_recbuf) { max_recbuf = abs(recbuf[recbufindex]); // keep track of largest sample } recbufindex++; if (recbufindex>=(2*N+2*M)) { state = STATE_WAIT_CLOCK; // buffer is full (stop recording and start counting samples to next clock tick) recbufindex = 0; // shouldn't be necessary wait_count = 0; // reset the wait counter if (max_recbuf<2048) playback_scale = 0; // don't send response (signal was too weak) else if (max_recbuf<4096) playback_scale = 8; // reply and scale by 8 else if (max_recbuf<8192) playback_scale = 4; // reply and scale by 4 else if (max_recbuf<16384) playback_scale = 2; // reply and scale by 2 else playback_scale = 1; // no scaling } } else if (state==STATE_WAIT_CLOCK) { // WAITING STATE (counting up samples until clock tick) if(ledTriggered){ DSK6713_LED_toggle(0); ledTriggered = 0; } if (PASSTHROUGH!=1) { temp.channel[0] = 0; // can comment this out for debugging at home } wait_count++; // only way out of this state is when the virtual clock rolls over } else if (state==STATE_WAIT_PLAYBACK) { // WAITING STATE (counting down samples until reply) if (PASSTHROUGH!=1) { temp.channel[0] = 0; // can comment this out for debugging at home } wait_count--; if (wait_count<0) { state = 4; // done waiting, time to play back rec_buffer in reverse recbufindex = 2*N+2*M; } } else if (state==STATE_RESPOND) { // RESPONSE STATE (play back recording buffer in reverse) recbufindex--; if (recbufindex>=0) { temp.channel[0] = playback_scale*recbuf[recbufindex]; } else { state = STATE_SEARCH; // go back to searching } } temp.channel[1] = clockbuf[vclock_counter]; // master clock signal (always played) MCBSP_write(DSK6713_AIC23_DATAHANDLE, temp.combo); // output L/R channels // update virtual clock (cycles from 0 to L-1) vclock_counter++; if (vclock_counter>=L) { vclock_counter = 0; // clock tick occurred, wrap if (state==STATE_WAIT_CLOCK) { state = STATE_WAIT_PLAYBACK; } } }
interrupt void serialPortRcvISR() { union {Uint32 combo; short channel[2];} temp; temp.combo = MCBSP_read(DSK6713_AIC23_DATAHANDLE); // Note that right channel is in temp.channel[0] // Note that left channel is in temp.channel[1] // keep track of largest sample for diagnostics if (temp.channel[0]>max_samp) max_samp = temp.channel[0]; // filter inbuf[inindex] = (float) temp.channel[0]; // right channel if (CLOCKOUTPUTCHANNEL==0) { // superimposed clocks and sync pulses, need to use HPF to avoid false detections hpfout = 0.0; ii = 0; for (kk=inindex;kk>=0;kk--){ hpfout += inbuf[kk]*B[ii]; ii++; } for (kk=BL-1;kk>inindex;kk--){ hpfout += inbuf[kk]*B[ii]; ii++; } } else { // clocks on left output, no need for HPF hpfout = (float) temp.channel[0]; // right channel } if (state==0) { // SEARCHING STATE // put sample in searching buffer fbuf[bufindex] = hpfout; // right channel buf[bufindex] = (float) temp.channel[0]; // unfiltered right channel if (PASSTHROUGH!=1) { temp.channel[0] = 0; // can comment this out for debugging at home } // compute incoherent correlation on filtered buffer zc = 0; zs = 0; for(i=0;i<M;i++) { zc += mfc[i]*fbuf[i]; zs += mfs[i]*fbuf[i]; } z = zc*zc+zs*zs; if (z>T1) { // threshold exceeded? if (z<minz) minz = z; // diagnostic if (z>maxz) maxz = z; // diagnostic max_recbuf = 0; state = 1; // enter "recording" state (takes effect in next interrupt) DSK6713_LED_toggle(0); // toggle LED for diagnostics recbufindex = M; // start recording new samples at position M j = bufindex; // for (i=0;i<M;i++){ // copy samples from buf to first M elements of recbuf j++; // the first time through, this puts us at the oldest sample if (j>=M) j=0; //recbuf[i] = (short) buf[j]; // Oct 28 bad idea recbuf[i] = (short) fbuf[j]; // DRB: filtered buffer copied now to avoid echoing back clock pulses fbuf[j] = 0; // clear out searching buffer to avoid false trigger buf[j] = 0; // clear out searching buffer to avoid false trigger } } else { // increment and wrap pointer bufindex++; if (bufindex>=M) bufindex = 0; } } else if (state==1) { // RECORDING STATE // put sample in recording buffer //recbuf[recbufindex] = temp.channel[0]; // right channel recbuf[recbufindex] = (short) hpfout; // filtered right channel if (PASSTHROUGH!=1) { temp.channel[0] = 0; // can comment this out for debugging at home } if (abs(recbuf[recbufindex])>max_recbuf) { max_recbuf = abs(recbuf[recbufindex]); // keep track of largest sample for diagnostics } recbufindex++; if (recbufindex>=(2*N+2*M)) { state = 2; // buffer is full (stop recording and start counting samples to next clock tick) DSK6713_LED_toggle(0); // toggle LED for diagnostics recbufindex = 0; // shouldn't be necessary wait_count = 0; // reset the wait counter if (max_recbuf<2000) playback_scale = 0; // don't send response (signal was too weak) else if (max_recbuf<4000) playback_scale = 8; // reply and scale by 8 (DRB now 4 to avoid overflow) else if (max_recbuf<8000) playback_scale = 4; // reply and scale by 4 (DRB now 2 to avoid overflow) else if (max_recbuf<16000) playback_scale = 2; // reply and scale by 2 (DRB now 1 tp avoid overflow) else playback_scale = 1; // no scaling } } else if (state==2) { // WAITING STATE (counting up samples until clock tick) if (PASSTHROUGH!=1) { temp.channel[0] = 0; // can comment this out for debugging at home } wait_count++; // only way out of this state is when the virtual clock rolls over } else if (state==3) { // WAITING STATE (counting down samples until reply) if (PASSTHROUGH!=1) { temp.channel[0] = 0; // can comment this out for debugging at home } wait_count--; if (wait_count<HPFGROUPDELAY) { state = 4; // done waiting, time to play back rec_buffer in reverse recbufindex = 2*N+2*M; } } else if (state==4) { // RESPONSE STATE (play back recording buffer in reverse) recbufindex--; if (recbufindex>=0) { temp.channel[0] = playback_scale*recbuf[recbufindex]; // response always on right channel } else { state = 0; // go back to searching } } // temp.channel[0] right channel has been previously set temp.channel[1] = 0; // clear left channel temp.channel[CLOCKOUTPUTCHANNEL] += clockbuf[vclock_counter]; // master clock signal (always played) // temp.channel[0] = temp.channel[1]; // XXX DIAGNOSTIC FOR OUTPUT OFFSET TEST // temp.channel[0] = clockbuf[vclock_counter]; // XXX DIAGNOSTIC MCBSP_write(DSK6713_AIC23_DATAHANDLE, temp.combo); // output L/R channels // update virtual clock (cycles from 0 to L-1) vclock_counter++; if (vclock_counter>=L) { vclock_counter = 0; // clock tick occurred, wrap if (state==2) { state = 3; } } inindex++; if (inindex>BL-1) inindex = 0; }