;This file is available with the DSK tools from Texas Instruments ; DAQ.ASM BASED ON SCOPE APPLICATION EXAMPLE PROVIDED WITH DSK.Fs=44.6 KHz ;This application is written to run with the DOS executable DAQ.EXE ; The initialization code which is used only on startup is placed inside ; the volatile data memory array to gain back internal memory. ;SAMPLING RATES ; The AIC sampling rates can be set to any combination which can still ; communicate with the DSP. Some combinations will work as high as 130 KHz ; with substantial performance degradation. Experimentation is required to ; find values that work best, or at all, since some will crash the ; communications entirely. ;HOST SYNCHRONIZATION ; Since the host should not disturb the ADC while data is being collected ; an interlock is used to keep the host from timing out. This application ; uses a message box. ;SERIAL PORT REFRESH ; If the serial port is not serviced once every frame synch an underrun ; condition will occur and the port will shut down. This is important for ; the transmit section since putting a new value in the DXR will cause the ; previous value to move to the shift register irregardless of the state ; of FSX. Since the bit patterns are data dependent and in this case shifted ; by an unknown amount the AIC could be reprogrammed if steps are not taken ; to avoid a bad restart. This is done by placing a zero in the transmitter ; whenever the serial port and AIC are likely to underrun. ; To prevent this the communications kernel is written such that the serial ; port tranmit channel is updated with zero whenever the kernel enters the ; wait for command loop 'spin0'. When spin0 is exited (RUN command) the ; serial port is restarted with the original value. ;------------------------------------------------------------------------- TA .set 10 ; Default startup values TB .set 14 ; RA .set 10 ; Default startup values RB .set 14 ; .include "C3XMMRS.ASM" .start "AICTEST",0x809900 .sect "AICTEST" GIE .set 0x2000 _STOP .set 1 _START .set 2 MSG_BOX .word _STOP ; 0x809900 TLVL .word 1000 ; 0x809901 A_REG .word (TA<<9)+(RA<<2)+0 ; 0x809902 B_REG .word (TB<<9)+(RB<<2)+2 ; 0x809903 C_REG .word 00000011b ; 0x809904 +/- 6 V ;EDGESEL .word 0 ; 0x809905 SAMPLES .word 512 ; 0x809906 A_REGOLD .word 0 B_REGOLD .word 0 C_REGOLD .word 0 OSC_DATA .word O_DATA S0_gctrl_val .word 0x0E970300 ; Runtime value XINT/RINT enabled S0_xctrl_val .word 0x00000111 ; S0_rctrl_val .word 0x00000111 ; main ldi 0x30,IE ; Ignore the host while collecting data ldi @S0_rdata,R0 ; Clear SP under/overflow ldi 0,R0 ; sti R0,@S0_xdata ; ldi @S0_rdata,R0 ; ldi 0,R0 ; sti R0,@S0_xdata ; ldi 25,RC ; Preload some ADC data to flush out rptb preload ; the AIC after putting it to sleep preload call GETADC ; ldi @OSC_DATA,AR0 ; ldi @SAMPLES,RC ; Now get samples, packed two/loop rptb samples ; packing 2 ints per word call GETADC ; Get a data point ldi R0,R2 ; Load the value into R2 and 0xFFFF,R2 ; Apply mask to R2 call GETADC ; Get the next data point lsh 16,R0 ; or R2,R0 ; samples sti R0,*AR0++ ; store to data array ldi 0,R0 ; The host may take some time to complete sti R0,@S0_xdata ; all tasks so use a safe DXR shut down value ldi 0x4,IE ; Only service host interrupts now ldi _START,R0 ; NO_START cmpi @MSG_BOX,R0 ; Restart when START message is received bnz NO_START ; ldi _STOP,R0 ; Set MSG box to STOP sti R0,@MSG_BOX ; cmpi 0,R2 ; bz main ; call AIC_INIT ; Restart with new AIC setup b main ; Do it all over again! RAMP .word 0 ; FLAGS .word 0 GETADC ldi 0x30,IE ; Come here and wait for ADC interrupt IDLE ; confirmation to save power and code space ldi @FLAGS,R0 ; tstb 0x20,R0 ; bz $-3 ; andn 0x20,R0 ; sti R0,@FLAGS ; ldi @S0_rdata,R0 ; Return sign extended ADC value lsh 16,R0 ; ash -16,R0 ; rets ADC push ST ; On interrupt, set a software flag to push R0 ; let the CPU know that the RINT has been ldi @S0_rdata,R0 ; ldi @FLAGS,R0 ; or 0x20,R0 ; sti R0,@FLAGS ; pop R0 ; pop ST ; reti ; DAC push ST ; push R1 ; ldi @RAMP,R1 ; Send RAMP signal out DAC for loopback test subi 256,R1 ; lsh 17,R1 ; Decrease ash -17,R1 ; andn 3,R1 ; sti R1,@RAMP ; sti R1,@S0_xdata ; loopback ADC->DAC pop R1 pop ST reti ;-------------------------------- prog_AIC push R1 ; push IE ; ldi 0x10,IE ; andn 0x30,IF ; ldi @S0_xdata,R1 ; Use original DXR data during 2 ndy sti R1,@S0_xdata ; idle ldi @S0_xdata,R1 ; Use original DXR data during 2 ndy or 3,R1 ; Request 2 ndy XMIT sti R1,@S0_xdata ; idle ; sti R0,@S0_xdata ; Send register value idle ; andn 3,R1 ; sti R1,@S0_xdata ; Leave with original safe value in DXR pop IE ; pop R1 ; rets ; ;======================================================; ; This section of code is called by the initialization ; ; code as well as by the main program loop. It is ; ; therefor assembled into the regular program RAM ; ;======================================================; AIC_INIT push R0 ; LDI 0x10,IE ; Enable XINT interrupt andn 0x34,IF ; AIC_reset ldi 0,R0 ; sti R0,@S0_xdata ; RPTS 0x040 ; LDI 2,IOF ; XF0=0 resets AIC rpts 0x40 ; LDI 6,IOF ; XF0=1 runs AIC ldi @S0_rdata,R0 ldi 0,R0 sti R0,@S0_xdata ldi @C_REG,R0 ; Setup control register call prog_AIC ; ldi 0xfffc ,R0 ; Program the AIC to be real slow call prog_AIC ; ldi 0xfffc|2,R0 ; call prog_AIC ; ldi @B_REG,R0 ; Bump up the Fs to final rate call prog_AIC ; (smallest divisor should be last) ldi @A_REG,R0 ; call prog_AIC ; pop R0 ; ldi 0,R0 ; Put a safe 0 in DXR sti R0,@S0_xdata ; ldi @S0_rdata,R0 ; Clear receive underrun rets ; ;------------------------------------------- .start "OSCDATA",0x809A00 .sect "OSCDATA" O_DATA .word 0 ; The following section of code is used only once for ; ; initialization and can be safely overwritten by ; ; assembling it into the stack or volatile data ; ; storage. ; .entry ST_STUB ST_STUB ldp T0_ctrl ; Use kernel data page and stack ldi 0,R0 ; Halt TIM0 & TIM1 sti R0,@T0_ctrl ; sti R0,@T1_ctrl ; sti R0,@T0_count ; Set counts to 0 sti R0,@T1_count ; ldi 1,R0 ; Set periods to 1 sti R0,@T0_prd ; sti R0,@T1_prd ; ldi 0x2C1,R0 ; Restart both timers sti R0,@T0_ctrl ; sti R0,@T1_ctrl ; ldi @S0_xctrl_val,R0; sti R0,@S0_xctrl ; transmit control ldi @S0_rctrl_val,R0; sti R0,@S0_rctrl ; receive control ldi 0,R0 ; sti R0,@S0_xdata ; DXR data value ldi @S0_gctrl_val,R0; Setup serial port sti R0,@S0_gctrl ; global control call AIC_INIT ; Initialize the AIC ldi 0x30,IE ; Service both RINT/XINT ldi @S0_rdata,R0 ; ; ldi 0,R0 ; Put a safe 0 in DXR ; sti R0,@S0_xdata ; b main ; S0_dxr .word S0_xdata ; Install the XINT/RINT ISR handler directly into ; ; the vector RAM location it will be used in ; .start "SP0VECTS",0x809FC5 .sect "SP0VECTS" b DAC ; XINT0 b ADC ; RINT0 .end