/* /////////////////////////////////////////////////////////////////////////////////// / FIR_Demo.asm 21161 EZ-KIT LITE SIMDFIR digital filter / / / / Receives input from the AD1836 A/D's via the 21161 serial port (SPORT1), / / Filters the data using a Finite Impuse Response Filter, and then stores the / / output for the SPORT1 ISR to transmit the data back to the AD1836 D/A's. / / / / The digital filter coefficients are in the files "high1.dat" and "low1.dat" / / / / The samples from the AD1836 are 24-bits and are are converted to / / floating point numbers. The values are also scaled to the range +/-1.0 / / with the integer to float conversion (f0 = float r0 by r1). / / / / The digital filtering takes place in the SPORT1 transmit interrupt service / / routine. / / / / See the "ADSP-21000 Family Applications Handbook Vol. 1" for more information / / regarding the implementation of digital filters (chapter 4) / / / / / /////////////////////////////////////////////////////////////////////////////////// */ /* ADSP-21161 System Register bit definitions */ #include "def21161.h" .GLOBAL Goertzel; .section /dm dm_data; /*---------------------------------------------------------------------------*/ .section /pm pm_data; .section /pm pm_code; .EXTERN RX_left_flag; .EXTERN Left_Channel_In1; .EXTERN Right_Channel_In1; .EXTERN Left_Channel_Out0; .EXTERN Right_Channel_Out0; .EXTERN Left_Channel_Out1; .EXTERN Right_Channel_Out1; .section /pm pm_code; Goertzel: r1=0; r0=dm(numer_probki); //odczytanie numeru probki r0=r0-1; comp(r0,r1); IF EQ JUMP liczenie; //ktora probka jak 6 to skok nop;nop; dm(numer_probki)=r0; jump koniec_procedury; liczenie: call Blink_LEDs_Test; r0=6; //zliczanie probek od nowa dm(numer_probki)=r0; //nowa wartosc licznika probek 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; r1=202; r0=dm(ile_zliczen); r0=r0+1; dm(ile_zliczen)=r0; COMP(R0,R1); IF EQ JUMP tylko_podst; nop;nop; M8=1; M9=0; I8=harm_Q1; I9=harm_Q2; I10=coefh; LCNTR=8, DO aktual_obie UNTIL lce; F0=dm(I0,M1), F4=pm(I8,M9); //Qk(n-1) F1=dm(I1,M1), F5=pm(I9,M9); //Qk(n-2) F2=dm(I2,M0), F6=pm(I10,M8);//coef F2=F0*F2;//COEF*Qk(n-1) F1=F1-F3,DM(I1,M0)=F0,PM(I9,M8)=F4;//Qk(n-2)-x(n) F6=F4*F6;//COEF*Qk(n-1) harm F5=F5-F3;//Qk(n-2)-x(n) harm F2=F2-F1; F6=F6-F5; DM(I0,M0)=F2,PM(I8,M8)=F6; aktual_obie: nop; JUMP koniec_procedury; nop;nop; tylko_podst: 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; r1=204; //a moze 204 comp(r0,r1); IF NE JUMP koniec_procedury; nop;nop; //tutaj faza koncowa r1=0; M0=1; M1=0; I0=podst_Q1; I1=podst_Q2; I2=coefp; M8=1; M9=0; I8=harm_Q1; I9=harm_Q2; I10=coefh; LCNTR=8, DO war_moc UNTIL lce; F0=dm(I0,M1), F4=pm(I8,M9); //Qk(n-1) F1=dm(I1,M1), F5=pm(I9,M9); //Qk(n-2) F2=dm(I2,M0), F6=pm(I10,M8);//coef F8=dm(I0,M1), F10=pm(I8,M9); //Qk(n-1) F9=dm(I1,M1), F11=pm(I9,M9); //Qk(n-2) F2=F0*F2;//COEF*Qk(n-1) F2=F2*F1; F0=F0*F8; F1=F1*F9; F6=F4*F6;//COEF*Qk(n-1) harm F6=F6*F5; F4=F4*F10; F5=F5*F11; F0=F0+F1; F0=F0-F2; //Yk(n) F4=F4+F5; F4=F4-F6; //Yk(n) - harm DM(I0,M0)=F2,PM(I8,M8)=F6; war_moc: nop; //tuatj mamy juz wartosci po goertzel'u //teraz szukamy maks kol i wier M0=1; M1=4; I0=podst_Q1; I1=podst_Q1; F0=dm(I0, M0); //F0 wartosc pierwszego wiersz; F4=dm(M1, I1); //F4 wartosc pierwszej kolumny; R2=0;//R2 - numer wiersza o max mocy R6=0;//R6 - numer kolumny o max mocy R7=0;//LICZNIK F8=1.0000; F5=DM(I1,M0); LCNTR=3, DO max_war UNTIL lce; F7=F7+F8; F5=MAX(F4,F5),F1=DM(I0,M0); COMP(F5,F4); //CZY ZMIENIONO WARTOSC MOCY IF EQ JUMP nie_kol; nop;nop; F4=F5; R6=R7; nie_kol: F1=MAX(F0,F1),F5=DM(I1,M0); COMP(F1,F0); //CZY ZMIENIONO WARTOSC MOCY IF EQ JUMP max_war; nop;nop; F0=F5; R2=R7; max_war: nop; //MAMY JUZ ZIDENT. WIER I KOL O MAKS MOCY F1=10.000; COMP(F0,F1); IF LE JUMP nie_wykryto; nop;nop; COMP(F4,F1); IF LE JUMP nie_wykryto; nop;nop; F1=0.158; F1=F1*F4; COMP(F0,F1); IF LT JUMP nie_wykryto; nop;nop; F1=0.158; F1=F1*F0; COMP(F4,F1); IF LT JUMP nie_wykryto; nop;nop; //mamy sprawdzony poziom sygnalu o ile byl:) F1=0.2; F5=0; COMP(F0,F4); IF GE JUMP wiekszy_wiersz; nop;nop; F1=F1*F4; JUMP czy_druga_czest; nop;nop; wiekszy_wiersz: F1=F1*F0; czy_druga_czest: M0=1; M1=0; I0=podst_Q1; LCNTR=8, DO spr_2_czest UNTIL lce; //druga czestotliwosc o wysokim poziomie F2=dm(I0,M0); COMP(F1,F2); IF GT JUMP wszyst_OK; nop;nop; F5=1.000; wszyst_OK: spr_2_czest: nop; f1=1.000; comp(f1,f5); if eq jump nie_wykryto; nop;nop; //teraz poziom drugich harmonicznych /*M0=R2; M8=R2; R5=4; R5=R5+R6; M1=R5; M9=R5; I0=podst_Q1; I8=harm_Q1; F3=0.2000; F1=dm(M0,I0); //wartosci wiersza F5=pm(M8,I8); //wartosci wiersza harm F1=F1*F3; //podstawowa zmniejszona comp(F1,F5);//jesli mniejsza rowna to nie dobrze IF LE JUMP nie_wykryto; nop;nop; I0=podst_Q1; I8=harm_Q1; F1=dm(M1,I0); //wartosc sygnalu kolumny F5=pm(M9,I8); //wartosci kolumny harmon F1=F1*F3; //podstawowa zmniejszona comp(F1,F5);//jesli mniejsza rowna to nie dobrze IF LE JUMP nie_wykryto; nop;nop; */ //wyswietlamy liczbe DTMF I0=liczba_DTMF; R2=LSHIFT R2 BY 2; R2=R2+R6; //numer wiersza razy 4 plus numer kolumny M0=R2; // ustat2=dm(IOFLAG); // bit set ustat2 FLG9O|FLG8O|FLG7O|FLG6O|FLG5O|FLG4O; // bit clr ustat2 FLG9|FLG8|FLG7|FLG6|FLG5|FLG4; /* clear flags to start*/ // dm(IOFLAG)=ustat2; //zapalenie numeru diody call Blink_LEDs_Test; nie_wykryto: //zerujemy wartosci poczatkowe Q1 i Q2 M0=1; I0=podst_Q1; I1=podst_Q2; M8=1; I8=harm_Q1; I9=harm_Q2; f7=0; f8=0; LCNTR=8, DO zerowanie UNTIL lce; DM(I0,M0)=F7,PM(I8,M8)=F8; DM(I1,M0)=F7,PM(I9,M8)=F8; zerowanie: nop; r0=6; //zliczanie probek od nowa dm(numer_probki)=r0; //nowa wartosc licznika probek r0=0; dm(ile_zliczen)=r0; koniec_procedury: //call Blink_LEDs_Test; RTS; Goertzel.end: