/**************************************************************************************************** / / / AD1836 - SPORT0 RX INTERRUPT SERVICE ROUTINE / / / / Receives input data from the 2 AD1836 ADCs via SPORT1 and transmits processed audio data / / back out to the 3 AD1836 Stereo DACs/Line Outputs / / / ***************************************************************************************************** / / / This Serial Port 0 Recieve Interrupt Service Routine performs arithmetic computations on / / the SPORT1 receive DMA buffer (rx_buf) and places results to SPORT1 transmit DMA buffer (tx_buf)/ / / / rx0a_buf[8] - DSP SPORT recieve buffer / / Slot # Description DSP Data Memory Address / / ------ -------------------------------------- ----------------------------------------------- / / 0 Internal ADC 0 Left Channel DM(rx0a_buf + 0) = DM(rx0a_buf + Internal_ADC_L0) / / 1 Internal ADC 1 Left Channel DM(rx0a_buf + 1) = DM(rx0a_buf + Internal_ADC_L1) / / 2 External Auxilliary ADC 0 Left Chan. DM(rx0a_buf + 2) = DM(rx0a_buf + AUX_ADC_L0) / / 3 External Auxilliary ADC 1 Left Chan. DM(rx0a_buf + 3) = DM(rx0a_buf + AUX_ADC_L1) / / 4 Internal ADC 1 Right Channel DM(rx0a_buf + 4) = DM(rx0a_buf + Internal_ADC_R0) / / 5 Internal ADC 1 Right Channel DM(rx0a_buf + 5) = DM(rx0a_buf + Internal_ADC_R1) / / 6 External Auxilliary ADC 0 Right Chan. DM(rx0a_buf + 6) = DM(rx0a_buf + AUX_DAC_R0) / / 7 External Auxilliary ADC 1 Right Chan. DM(rx0a_buf + 7) = DM(rx0a_buf + AUX_DAC_R1) / / / / tx2a_buf[8] - DSP SPORT transmit buffer / / Slot # Description DSP Data Memory Address / / ------ -------------------------------------- ----------------------------------------------- / / 0 Internal DAC 0 Left Channel DM(tx0a_buf + 0) = DM(tx0a_buf + Internal_DAC_L0) / / 1 Internal DAC 1 Left Channel DM(tx0a_buf + 1) = DM(tx0a_buf + Internal_DAC_L1) / / 2 Internal DAC 2 Left Channel DM(tx0a_buf + 2) = DM(tx0a_buf + Internal_DAC_L2) / / 3 External Auxilliary DAC 0 Left Chan. DM(rx0a_buf + 3) = DM(tx0a_buf + AUX_DAC_L0) / / 4 Internal DAC 0 Right Channel DM(tx0a_buf + 4) = DM(tx0a_buf + Internal_DAC_R0) / / 5 Internal DAC 1 Right Channel DM(tx0a_buf + 5) = DM(tx0a_buf + Internal_DAC_R1) / / 6 Internal DAC 2 Left Channel DM(tx0a_buf + 6) = DM(tx0a_buf + Internal_DAC_R3) / / 7 External Auxilliary DAC 0 Right Chan. DM(tx0a_buf + 7) = DM(tx0a_buf + AUX_DAC_R0) / / / ****************************************************************************************************/ /* ADSP-21161 System Register bit definitions */ #include "def21161.h" /* AD1836 TDM Timeslot Definitions */ /* 8 successive 32 bit samples (representing 8 channels of audio data) make up the 256 bit TDM frame */ #define Internal_ADC_L0 0 #define Internal_ADC_L1 1 #define AUX_ADC_L0 2 #define AUX_ADC_L1 3 #define Internal_ADC_R0 4 #define Internal_ADC_R1 5 #define AUX_ADC_R0 6 #define AUX_ADC_R1 7 #define Internal_DAC_L0 0 #define Internal_DAC_L1 1 #define Internal_DAC_L2 2 #define AUX_DAC_L0 3 #define Internal_DAC_R0 4 #define Internal_DAC_R1 5 #define Internal_DAC_R2 6 #define AUX_DAC_R0 7 .GLOBAL Process_AD1836_Audio_Samples; /* Label of code listed here to get samples into and out of*/ /* SPORT DMA buffers and process_audio routine*/ .GLOBAL Left_Channel_In0; /* These will tranfer ADC samples of interest from the*/ .GLOBAL Right_Channel_In0; /* Process_AD1836_Audio_Samples routine to the process_audio routine*/ .GLOBAL Left_Channel_In1; .GLOBAL Right_Channel_In1; .GLOBAL Left_Channel_SPDIF_rx; .GLOBAL Right_Channel_SPDIF_rx; .GLOBAL Left_Channel_Out0; /* These will bring samples for the DACs back into the*/ .GLOBAL Right_Channel_Out0; /* Process_AD1836_Audio_Samples routine from the process_audio routine*/ .GLOBAL Left_Channel_Out1; .GLOBAL Right_Channel_Out1; .GLOBAL Left_Channel_Out2; .GLOBAL Right_Channel_Out2; .GLOBAL Left_Channel_AD1852; .GLOBAL Right_Channel_AD1852; //.GLOBAL Left_Channel_Out_Thru; /* These serve the same function for a different set of audio */ //.GLOBAL Right_Channel_Out_Thru; /* samples destined for the DACs*/ .EXTERN tx2a_buf; /* These are the DMA buffers that hold the 8 channels of audio */ .EXTERN rx0a_buf; /* immediately pre-transmission and post-reception */ .EXTERN Goertzel; /* Label of audio algorithm code listed in another file which executes */ /* a procesing alogorithm on the audio data before it is output */ /* to the DACs */ //.EXTERN Left_Channel_Out_Thru; /* These serve the same function for a different set of audio */ //.EXTERN Right_Channel_Out_Thru; /* samples destined for the DACs*/ .EXTERN Blink_LEDs_Test; .section /dm dm_codec; /* AD1836 stereo-channel data holders - used for DSP processing of audio data received from codec */ .VAR Left_Channel_In0; /* Input values from AD1836 ADCs */ .VAR Left_Channel_In1; .VAR Right_Channel_In0; .VAR Right_Channel_In1; .VAR Left_Channel_SPDIF_rx; .VAR Right_Channel_SPDIF_rx; .VAR Left_Channel_Out0; /* Output values for AD1836 DACs */ .VAR Left_Channel_Out1; .VAR Left_Channel_Out2; .VAR Right_Channel_Out0; .VAR Right_Channel_Out1; .VAR Right_Channel_Out2; .VAR Left_Channel_AD1852; .VAR Right_Channel_AD1852; .VAR Left_Channel; /* can use for intermediate results to next filter stage */ .VAR Right_Channel; /* can use for intermediate results to next filter stage */ /* TDM audio frame/ISR counter, for debug purposes */ .VAR audio_frame_timer = 0; .var ile_zliczen=0; .var podst_Q1[8]= 0,0,0,0,0,0,0,0; .var podst_Q2[8]= 0,0,0,0,0,0,0,0; .var coefp[8]= 1.99155133, 1.98957126, 1.98738353, 1.98498837, 1.97497552, 1.96991047, 1.96243767, 1.95414554; .var liczba_DTMF[16]= 0x0F01, 0x0F02, 0x0F03, 0x0F0A, 0x0F04, 0x0F05, 0x0F06, 0x0F0B, 0x0F07, 0x0F08, 0x0F09, 0x0F0C, 0x0F0E, 0x0F0F, 0x0F0F, 0x0F0D; .section /pm pm_code; Process_AD1836_Audio_Samples: r0 = dm(rx0a_buf + Internal_ADC_R1); dm(Right_Channel_In1) = r0; do_audio_processing: /* if (sample_count < 1230) { sample_count++; for (i=0; i<8; i++) // Realizacja jednego kroku algorytmu dla wszystkich czestotliwosci { q0 = goertzel_coef[i] * q1[i] - q2[i] + sample; q2[i] = q1[i]; q1[i] = q0; } }*/ r0=dm(ile_zliczen); r1=1230; COMP(R0,R1); IF GE JUMP faza_konc; r0=r0+1;//kolejna probka dm(ile_zliczen)=r0; //i obliczenie fazy pierwszej r1=-31; r0=dm(Right_Channel_In1); F3=float r0 by r1; //wartosc odebranej probki jako float M0=1; M1=0; I0=podst_Q1; I1=podst_Q2; I2=coefp; //osiem podstawowych czestotliwosc LCNTR=8, DO aktual_podst UNTIL lce; F0=dm(I0,M1); //Qk(n-1) F1=dm(I1,M1); //Qk(n-2) F2=dm(I2,M0);//coef F2=F0*F2;//COEF*Qk(n-1) F1=F1-F3,DM(I1,M0)=F0;//Qk(n-2)-x(n) F2=F2-F1; DM(I0,M0)=F2; aktual_podst: nop;nop; jump koniec_procedury; /* else { // Obliczenie mocy skladowych i zerowanie pamieci dla nastepnego pomiaru for (i=0; i<8; i++) { r[i] = (q1[i] * q1[i]) + (q2[i] * q2[i]) - (goertzel_coef[i] * q1[i] * q2[i]); q1[i] = 0; q2[i] = 0; } */ faza_konc: r0=0; dm(ile_zliczen)=r0; /*sample_count = 0;*/ M0=1; M1=0; I0=podst_Q1; I1=podst_Q2; I2=coefp; LCNTR=8, DO war_moc UNTIL lce; F0=dm(I0,M1); //Qk(n-1) f8=f0; F1=dm(I1,M0); //Qk(n-2) f9=f1; F2=dm(I2,M0);//coef F2=F0*F2;//COEF*Qk(n-1) F2=F2*F1; F0=F0*F8;//Qk(n-1)^2 F1=F1*F9;//Qk(n-2)^2 F0=F0+F1;//Qk(n-2)^2 + Qk(n-1)^2 F0=F0-F2; //Yk(n) DM(I0,M0)=F0; war_moc: nop;nop; /* // Interpretacja odczytu: // Odczyt stanu LED: Leds = *(int*) IOFLAG; Leds &= ~(FLG4|FLG5|FLG6|FLG7|FLG8|FLG9); // Najwiekszy w wierszu: row = 0; maxval = 0; for (i=0; i<4; i++) { if ( r[i] > maxval ) { maxval = r[i]; row = i; } } // Najwiekszy w kolumnie: col = 4; maxval = 0; for (i=4; i<8; i++) { if ( r[i] > maxval ) { maxval = r[i]; col = i; } } */ M0=1; M1=4; I0=podst_Q1; I1=podst_Q1; F0=dm(I0, M0); //F0 wartosc pierwszego wiersz; R2=0;//R2 - numer wiersza o max mocy F4=dm(I1, M1); //F4 wartosc pierwszej kolumny; F4=dm(I1, M0); //F4 wartosc pierwszej kolumny; R6=0;//R6 - numer kolumny o max mocy R7=0;//LICZNIK LCNTR=3, DO max_war UNTIL lce; r7=r7+1; //ikrementacja aktualnego numeru wiersza i kolumny F5=DM(I1,M0); COMP(F5,F4); //CZY ZMIENIONO WARTOSC MOCY IF LE JUMP nie_kol; F4=F5; R6=R7; nie_kol: F1=DM(I0,M0); COMP(F1,F0); //CZY ZMIENIONO WARTOSC MOCY IF LE JUMP max_war; F0=F1; R2=R7; max_war: nop;nop; /* // Minimalny poziom sygnalu if ((r[row] > 10) && (r[col] > 10)) {*/ F1=3.000; COMP(F0,F1); IF LE JUMP nie_wykryto; COMP(F4,F1); IF LE JUMP nie_wykryto; /* dtmf_ok = 1; if ( r[col] > r[row] ) { // Sprawdzenie "Normal twist" max_index = col; if ( r[row] < (r[col] * 0.158 ) ) // twist > 8dB, error dtmf_ok = 0; } else { // Sprawdzenie "Reverse twist" max_index = row; if ( r[col] < (r[row] * 0.158 ) ) // twist > 8db, error dtmf_ok = 0; }*/ F1=0.015; F1=F1*F4; COMP(F0,F1); IF LT JUMP nie_wykryto;// Sprawdzenie "Normal twist" F1=0.015; F1=F1*F0; COMP(F4,F1); IF LT JUMP nie_wykryto;// Sprawdzenie "Reverse twist" //t = r[max_index] * 0.200; F1=0.02; F1=F1*F0; COMP(F0,F4); IF GE JUMP czy_druga_czest; F1=F1*F4; czy_druga_czest: /* peak_count = 0; for ( i=0; i<8; i++ ) { if ( r[i] > t ) peak_count++; } if ( peak_count > 2 ) // wiecej niz 2 czestotliwosci - error dtmf_ok = 0; */ M0=1; I0=podst_Q1; F5=0; LCNTR=8, DO spr_2_czest UNTIL lce; //druga czestotliwosc o wysokim poziomie F3=dm(I0,M0); COMP(F1,F3); IF GE JUMP wszyst_OK; F3=1.000; F5=F5+F3; wszyst_OK: spr_2_czest: nop;nop; f1=2.000; comp(f5,f1); if GT jump nie_wykryto; //wyswietlamy liczbe DTMF I0=liczba_DTMF; R2=LSHIFT R2 BY 2; R2=R2+R6; //numer wiersza razy 4 plus numer kolumny m0=r2; wys: ustat2=dm(M0,I0); dm(IOFLAG)=ustat2; //zapalenie numeru diody lcntr=6250000; do opdelay until lce; opdelay: nop; bit set ustat2 FLG9O|FLG8O|FLG7O|FLG6O|FLG5O|FLG4O; bit clr ustat2 FLG9|FLG8|FLG7|FLG6|FLG5|FLG4; dm(IOFLAG)=ustat2; //zapalenie numeru diody */ nie_wykryto: //zerujemy wartosci poczatkowe Q1 i Q2 M0=1; I0=podst_Q1; I1=podst_Q2; r7=0; LCNTR=8, DO zerowanie UNTIL lce; DM(I0,M0)=r7; DM(I1,M0)=r7; zerowanie: nop;nop; koniec_procedury: tx_done: r0=dm(audio_frame_timer); /* get last count */// rti(db); /* return from interrupt, delayed branch */ r0=r0+1; /* increment count */ dm(audio_frame_timer)=r0; /* save updated count */ Process_AD1836_Audio_Samples.end: /* ////////////////////////////////////////////////////////////////////////////////// */