{___________________________________________________________________________ ECHO.ASM ADSP-21020 EZLAB Circular Buffer Demonstration Outputs the sum of samples with 7 different delays. Demonstrates the conversion of AD1849 samples from fixed point to floating point and back. To assemble this demo from scratch us the following commands: asm21k echo ld21k -a ezlab21k echo spl21k -a ezlab21k -ram -dm -pm -f B echo Author: 14-Feb-91, SLC Analog Devices Inc. DSP Division ____________________________________________________________________________} { ADSP-21020 System Register bit definitions } #include "def21020.h" #define LENGTH 32000 {___________________________________________________________________________} .SEGMENT/DM dm_sram; .VAR buffer[10]; {do not declare all 32k so it will load faster } .ENDSEG; .SEGMENT/DM hip_regs; .PORT in_audio_l; { ADSP-2111 HDR0 = Left input } .PORT in_audio_r; { ADSP-2111 HDR1 = Right input } .PORT out_audio_l; { ADSP-2111 HDR2 = Left output } .PORT out_audio_r; { ADSP-2111 HDR3 = Right output } .PORT control_0; { ADSP-2111 HDR4 } .PORT control_1; { ADSP-2111 HDR5 } .ENDSEG; .SEGMENT/DM dac_a; .PORT dac_a; .ENDSEG; .SEGMENT/DM dac_b; .PORT dac_b; .ENDSEG; .SEGMENT/DM adc_b; .PORT adc_b; .ENDSEG; {___________________________________________________________________________} .SEGMENT/PM rst_svc; { Reset Vector } call init_21k; call setup_1849; jump main; .ENDSEG; {___________________________________________________________________________} .SEGMENT/PM irq2_svc; { Push Button Interrupt } bit tst ustat1 2; { test if AD1849 setup mode is enabled } if not tf jump skip_setup; { for AD1849 setup } bit set ustat1 1; { for AD1849 setup } rti; { for AD1849 setup } skip_setup: { label for AD1849 setup } jump irq2_asserted; .ENDSEG; {___________________________________________________________________________} .SEGMENT/PM irq3_svc; { Audio I/O Interrupt } jump irq3_asserted (db); bit set mode1 SRD1L|SRD1H|SRRFL|SRRFH; { use all secondary registers} nop; .ENDSEG; {___________________________________________________________________________} .SEGMENT/PM tmzh_svc; { Timer Interrupt } jump timer_hi_prior; .ENDSEG; {___________________________________________________________________________} .SEGMENT/PM pm_sram; main: r0=0x00000100; { data to circulate through LEDs} ustat2 = 0; { starting state = 0 } bit set mode1 IRPTEN; { enable global int.} bit set mode2 TIMEN; { timer on! } bit set mode1 SRD1L|SRD1H|SRRFL|SRRFH; nop; b0=buffer; l0=LENGTH; b1=buffer; i1=buffer+LENGTH; l1=LENGTH; b2=buffer; i2=buffer+LENGTH - 1500; l2=LENGTH; b3=buffer; i3=buffer+LENGTH - 2500; l3=LENGTH; b4=buffer; i4=buffer+LENGTH - 5000; l4=LENGTH; b5=buffer; i5=buffer+LENGTH - 8000; l5=LENGTH; b6=buffer; i6=buffer+LENGTH - 11000; l6=LENGTH; b7=buffer; i7=buffer+LENGTH - 12000; l7=LENGTH; m1=1; f0=0; lcntr=LENGTH, do clear_buffer until lce; clear_buffer: dm(i0,1)=f0; bit clr mode1 SRD1L|SRD1H|SRRFL|SRRFH; nop; wait: idle; jump wait; {___________________________initialize the chip___________________________} init_21k: pmwait =0x1c21; { pgsz=32K,pmwtstates=0,sw.wtstates only} dmwait =0x70a421; { pgsz=32K,bank2_dmwtstates=1,sw.wtstates only} tperiod =0x3d08ff; { timer interrupt at 5 Hz } tcount = tperiod; irptl =0; bit set mode2 0x10; nop; read cache 0; bit clr mode2 0x10;{clr cache} {irq2&3 enable, timer enable high priority} bit set imask TMZHI|IRQ2I|IRQ3I; {irq2&3 edge sens, flag 1&2&3 outputs} bit set mode2 IRQ2E|IRQ3E|FLG1O|FLG2O|FLG3O; bit clr astat FLG1|FLG2|FLG3; { clear flag LEDs } rts; {__________________________Timer Interrupt__________________________________} timer_hi_prior: pop sts; { get ASTAT from stack, pushed there by IRQ } bit tgl astat FLG1; push sts; { restore stack so effect happens after rti } r3=dm(adc_b); { Read last ADC-B input } dm(adc_b)=r3; { write to ADC-B to start conversion } dm(dac_b)=r3; { output DAC-B value } rti; {__________________________IRQ2 Interrupt Vector____________________________} { Switch between 3 states and display the state on Flag 2 and 3 } irq2_asserted: { Change State } r0=ustat2; { get current state } r0=r0+1; { Increment state } r1=3; comp(r0,r1); if eq r0=r0 xor r0; { clear if going back to state 0 } ustat2=r0; { Reverse state for display on LEDs} r1=lshift r0 by -1; r0=bclr r0 by 1; r1=r1 or lshift r0 by 1; pop sts; { get ASTAT from stack, pushed there by IRQ } bit clr astat FLG2|FLG3; r0=astat; r0=r0 or lshift r1 by 21; astat=r0; push sts; { restore stack so effect happens after rti } rti; {__________________________IRQ3 Interrupt Vector____________________________} irq3_asserted: r4=dm(in_audio_r); { get AD1849 value } dm(out_audio_r)=r4; { get AD1849 value } r4=dm(in_audio_l); { get AD1849 value } r4=ashift r4 by -16; { Mask off 16 LSBs } r5=-16; { scale fractional value up and } f4=float r4 by r5; { convert to FLOAT } dm(i0,m1)=f4; { store one sample } f4=dm(i1,1); { get sample } f6=.5; f4=f4*f6; f5=dm(i2,1); f6=.3; f5=f5*f6; f4=f4+f5; f5=dm(i3,1); f6=.2; f5=f5*f6; f4=f4+f5; f5=dm(i4,1); f6=.1; f5=f5*f6; f4=f4+f5; f5=dm(i5,1); f6=.05; f5=f5*f6; f4=f4+f5; f5=dm(i6,1); f6=.04; f5=f5*f6; f4=f4+f5; f5=dm(i7,1); f6=.03; f5=f5*f6; f4=f4+f5; r5=32; { Scale fractional value up and } r4=fix f4 by r5; { convert to FIXED left justified } dm(out_audio_l)=r4; { output AD1849 value } r4=btgl r4 by 31; { invert the sign bit for DAC } dm(dac_a)=r4; { output DAC value } pop sts; push sts; rti; {_____________________Change Setup for the AD1849____________________________ Allows one to change the AD1849s setup from the default state using the FLAG and interrupt push buttons. Attributes that can be changed are: line or microphone input source, input gain, and the sample rate. Do not press the IRQ2 button too fast when changing the sample rate. The 2111 reboots and sets up the AD1849 each time the button is pressed, and will get confused if the button is pressed when this is happening. Initialization: flag0 must be setup as an input. irq2 must be enabled. ustat1 bits 0 and 1 are reserved to tell the irq2 if in setup mode. Operation: Press and hold button Press and release button Release button to enter the setup routine Push button to toggle between Line and Microphone input Push button to go to the next state Push button to change the input gain, (8 levels) Push button to go to the next state Push button to change the sample rate, (16 frequencies) Push button to exit the setup routine Microphone Input Gain Default: level 4 => 20dB + level*2*1.5dB = 34dB Line Input Gain Default: level 0 => level*2*1.5dB = 0dB Sample Rates: ( 0) 8 ( 8) 5.5125 ( 1) 16 (default) ( 9) 11.025 ( 2) 27.42857 (10) 18.9 ( 3) 32 (11) 22.05 ( 4) N/A (12) 37.8 ( 5) N/A (13) 44.1 ( 6) 48 (14) 33.075 ( 7) 9.6 (15) 6.615 ___________________________________________________________________________} setup_1849: bit clr ustat1 2; { clear the setup flag state } if not flag0_in jump exit_setup; yes_setup: if flag0_in jump yes_setup; { wait for flag button release } bit set ustat1 2; { set the setup flag } bit clr ustat1 1; { clear the irq2 pressed flag } bit set mode1 IRPTEN; { enable global int.} {....Set the AD1849 input source....} input_wait: bit tst ustat1 1; if tf jump set_input; if flag0_in jump level_state; jump input_wait; set_input: r0=dm(control_0); { read from 2111 hip } r0=btgl r0 by 30; { toggle between line and mic } r1=0xc0ffffff; { mask line gain default } r2=0x24000000; { mask mic gain default } btst r0 by 30; if sz r0 = r0 and r1; { its line so gain is 0 } if not sz r0 = r0 or r2; { its mic so gain is 4 } dm(control_0)=r0; { write to 2111 hip } bit clr ustat1 1; { reset the irq2 pressed flag } jump input_wait; {....Set the AD1849 input level....} level_state: if flag0_in jump level_state; { wait for release of flag button } bit clr ustat1 1; level_wait: bit tst ustat1 1; if tf jump set_level; if flag0_in jump sample_state; jump level_wait; set_level: r0=dm(control_0); { read from 2111 hip } {....bump up lg....} r1=lshift r0 by -24; r1=r1+1; { increment lg } r2=0x00000007; { modulo 8 for lg } r1=r1 and r2; r2=0xf8ffffff; { clear lg field } r0=r0 and r2; r0=r0 or lshift r1 by 24; {....bump up rg....} r1=lshift r0 by -27; r1=r1+1; { increment rg } r2=0x00000007; { modulo 8 for rg } r1=r1 and r2; r2=0xc7ffffff; { clear rg field } r0=r0 and r2; r0=r0 or lshift r1 by 27; {....output to 2111 hip....} dm(control_0)=r0; bit clr ustat1 1; { reset the irq2 pressed flag } jump level_wait; {....Set the AD1849 sample rate....} sample_state:if flag0_in jump sample_state; { wait for release of flag button } bit clr ustat1 1; sample_wait: bit tst ustat1 1; if tf jump set_sample; if flag0_in jump exit_setup; jump sample_wait; set_sample: r0=dm(control_1); { read from 2111 hip } r0=lshift r0 by -16; r0=r0+1; { increment sample rate } r0=lshift r0 by 16; r1=0x000f0000; { modulo 16 } r0=r0 and r1; dm(control_1)=r0; { output sample rate to 2111 hip } bit clr ustat1 1; { reset the irq2 pressed flag } jump sample_wait; exit_setup: if flag0_in jump exit_setup; { wait for release of flag button } bit clr ustat1 2; { clear the setup flag } rts; nop; nop; {___________________________________________________________________________} .ENDSEG;