Hi, Thank you all for sending me Code exlorer. I have come across some information that might be interesting. This is from help file of winDSK by Michael G. Morrow. A complication in writing DSK applications lies in the nature of the Host Port Interface (HPI) design. Communications between the host computer and the DSK result in the DSK processor becoming locked in an extended external bus cycle waiting for the host to complete each transaction. During this time, the processor cannot respond to interrupts and so cannot service the serial port interrupts caused by the Analog Interface Circuit (AIC). Older DOS-based tools were not affected by this, as DOS was a deterministic, single-task system so it could be counted on to complete a DSK transaction in immediate succession. With multi-tasking, multi-threaded operating systems such as Windows 9X, application programs can be suspended at any time as the operating system continuously shifts execution from thread to thread. If this occurs in the middle of a host-DSK exchange, the AIC will be unintentionally reprogrammed, generally resulting in the DSK processor losing communications with the AIC, and a loss of DSK audio functionality. winDSK overcomes this problem with a modified version of the Code Explorer communication/debugging kernel that uses the TMS320C31 direct memory access (DMA) controller to complete the HPI transfers. In this way, only the DMA controller becomes locked in the external bus cycle to the HPI during host-DSK transactions, while the processor can still service the serial port (and other) interrupts. This permits reliable operation of DSK applications while host-DSK communications proceed. Has anybody modified the DSK kernel to do this? About new DSK demos and debugger, How can I get them? Regards -Ninad Thakoor |
|
about C3x kernel
Started by ●March 19, 2002
Reply by ●March 19, 20022002-03-19
Err. this assesment is not quite right, nor is this solution the best for what I think you are looking for. If I am not mistaken, Michael modified the DSKWAV.ASM DOS/console based wave player/recorder (you may not this application does not suffer from any of the afformentioned problems), so you may want to look that over. There are several ways around this problem as described in the *.TXT files that accompany the DSK. The real problem ---------------- If you dig in you will find that the real problem is the serialy programmed AIC. (This is not a problem with the PCM3003 stereo daughter card mentioned later). - Being serialy programmed the AIC tends to want to reprogram itself whenever serial port updates are stopped. - Serial port updates are stopped during debug (this should be expected) and the AIC receives trash. - The serial port itself also wants to shutdown when no updates are being written. Again the AIC receives trash. Simple solution (see file below) -------------------------------- Use the DMA to continuously copy (without synchronization) a value stored at a memory location to the DXR, keeping both the serial port and AIC happy. The DAC is still not updated when the application is stopped for debug, so keep this in mind if you are working on a control application. The file that is attached below goes even further by showing you how to write ISR's that can also be debugged, all without corrupting the AIC. If you *really* want to use the DMA for HPI transfers ----------------- If the DMA is to be used for HPI transfers you need to replace the R_HOST and W_HOST routines (dont forget nibble/byte mode). The starting point would be the DMA HPI routines that are found in DSKWAV.ASM. Note... - Using the DMA to perform host transfers does not solve the AIC update problem when an application is stopped for debug mode. You would have to leave the serial interrupts enabled during debug. Not only is this tricky, but the main application loop that is probably maintaining what goes in and out is stalled... No bonus here! - Using the DMA for host transfers consumes the DMA (you can no longer use it in your application), and it consumes considerable memory since the send and receive values are unpacked. NOTE: DSK3D has the option of loading kernels other than C3X.DSK. If you start DSK3D with a '?' the help screen pops up and you will see a K.DSK option. You may want to consider that debugging a debug kernel is 'interesting'. More options ------------ Non Interlock Reads ------------------- Did you know that data can be read (or write) from the HPI without an interlock occuring? And since the PP dbus is essentialy held by the host, reception is relatively easy. The easy method is to poll the PP data bus each time your application completes a code loop using one of the lines as a strobe. This provides a simple if limited 'no-click' way to update values in an application. The Parametric EQ demo (works with PCM3003 stereo daughter card) and host control demo that I recently finished are two examples that use this method. On the other hand, sending data to the host does require the data to be held... But again, there is a C3x feature I bet no one here knows about. Did you know that if a value is written to the bus that it is 'posted' and the CPU can go on to the next task? As long as the CPU does not try to write to the bus before the first write is completed, the CPU will continue running. ;- ; DACOUT.ASM ; Keith Larson ; ; DACOUT uses the DMA to continuously update the serial port DXR ; even when the application is being debugged. ; ; When the loop in main is run, the floating point value at DAC_VOLTS ; is converted to the corresponding integer value. ; ; You can also directly poke integer values into DAC_INTEGER, but be ; extra careful to not use the bottom two LSB's. If you do, the AIC ; may decide to re-program itself. ; ; ADC and DAC interrupt routines are also included which are compatible ; with the DSK debugger. You can insert code here if you like. ; ;- .include "C3XMMRS.ASM" .start "AICTEST",0x809802; Start assembling here .sect "AICTEST" ; ; Define constants used by program ; GAIN .set 0 ; TIM0_PRD .set 1 ; Timer diviser TA .set 8 ; AIC timing register values TB .set 14 ; RA .set 8 ; RB .set 14 ; ;--------------------------- ; main ldi 25,R7 ; andn 0x04,IE ; disable host interrupts or 0x30,IE ; Enable XINT/RINT idle ; this is usualy where XINT/RINT are serviced idle andn 0x30,IE ; Then, during debug, or 0x04,IE or 2000h,ST ldi @S0_rdata,R0 ; Receiver underrun cleared by simple read b main RAMP .float 0 ;---------------- DAC_VOLTS .float 1.0 DAC_SCALE .float 4*16384.0/6.0 ; 6 volt full scale 14 bits, shift up by 2 DAC2 push ST ; since debugger uses INTs it enables them push IE ldi 0xC4,IE ; Cant debug an ISR while it is enabled DAC_DBG push R0 ; so start here pushf R0 ; push R1 ; pushf R1 ; push AR0 ; andn XINT,IE ; dont debug lines above here ldf @DAC_VOLTS,R0 ; mpyf @DAC_SCALE,R0 ; fix R0,R0 ; cmpi 32767,R0 ; ldigt 32767,R0 ; cmpi -32768,R0 ; ldilt -32768,R0 ; andn 3,R0 ; sti R0,@xdata ; Output DAC value to xdata ->DMA->XSR pop AR0 ; popf R1 ; pop R1 ; popf R0 ; pop R0 ; pop IE pop ST ; rets ; ;================================================================ ; The ADC receives its value as an analog loopback from the DAC ; With the controller point swinging from +/-P, the output should ; look different as the coefficients change ;---------------------------- ADC2 push ST ; Debugging here reenables INTs push IE ; so cant have RINT live at the same time ldi 0xC4,IE ; ADC_DBG push R0 ; pushf R0 ; ldi @S0_rdata,R0 ; Sign extend the data lsh 16,R0 ; Present data is in lower 16 bits ash -16,R0 ; >> Sample N-1 is in upper 16 bits float R0,R0 ; stf R0,@ADC_FLOATVAL; popf R0 ; pop R0 ; pop IE pop ST ; rets ; ;*****************************************************; ADC_FLOATVAL .float 0 ;----------- ; Define the serial port global control bits ;----------- XCLKSRCE .set 0 << 6 ; 0=external 1= internal RCLKSRCE .set 0 << 7 ; XVAREN .set 1 << 8 ; VAREN 0 1 RVAREN .set 1 << 9 ; FS ____---------_____ XFSM .set 0 <<10 ; 0=burst 1=continuous RFSM .set 0 <<11 ; CLKXP .set 0 <<12 ; CLKRP .set 0 <<13 ; DXP .set 0 <<14 ; DRP .set 0 <<15 ; FSXP .set 1 <<16 ; FSRP .set 1 <<17 ; XLEN .set 01b<<18 ; 00=8 01 10$ 112 RLEN .set 01b<<20 ; EXTINT .set 0 <<22 ; EXINT .set 1 <<23 ; ERTINT .set 0 <<24 ; ERINT .set 1 <<25 ; S0 .sdef XCLKSRCE|RCLKSRCE|XVAREN|RVAREN|XFSM|RFSM|CLKXP|CLKRP S0 .sdef S0|DXP|DRP|FSXP|FSRP|XLEN|RLEN|EXTINT|EXINT|ERTINT|ERINT S0_grst .word S0 S0_gctrl_val .word S0|0x0C000000 A_REG .word (TA<<9)+(RA<<2)+0 ; A registers B_REG .word (TB<<9)+(RB<<2)+2 ; B registers BPNBL .set 0 <<2 ; 1 nbls ADC band pass filter LOOPBACK .set 0 <<3 ; 1 nbls internal DAC->ADC connect AUXIN .set 0 <<4 ; 1 nbls AUXIN (AIN off) SYNC .set 0 <<5 ; 0 FSR/FSX can differ, 1 FSX/FSR are same GCTRL .set GAIN <<6 ; 0 b 1=+6db 2=+12db 3 b C_REG .word GCTRL|SYNC|AUXIN|LOOPBACK|BPNBL|11b ; control S0_xctrl_val .word 0x00000111 ; S0_rctrl_val .word 0x00000111 ; ;*****************************************************; ; The startup stub is used during initialization only ; ; and can be safely overwritten by the stack or data ; ;*****************************************************; .entry ST_STUB ; Debugger starts here ST_STUB ldp T0_ctrl ; Use kernel data page and stack ldi @stack,SP ldi 0,R0 ; Halt TIM0 sti R0,@T0_ctrl ; sti R0,@T0_count ; Zero the count ldi TIM0_PRD,R0 ; Set the period sti R0,@T0_prd ; ldi 0x2C1,R0 ; Restart the timer sti R0,@T0_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 ;======================================================; ; This section of code initializes the AIC ; ;======================================================; AIC_INIT LDI 0x10,IE ; Enable only XINT interrupt andn 0x34,IF ; 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 @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 ; or 0xC4,IE ; enable host and debug ints call DMA_PUMP b main ; ;================================ DMA_RUN .set 0x03 ; Write sync forever (write to XBUFR on XINT) DMA_STOP .set 0x0 ; DMA is reset and stopped DMA_DEST .word S0_xdata DMA_SRCE .word xdata xdata .word 0 DINT .set 0x400 RINT .set 0x020 XINT .set 0x010 DMA_XINT .word XINT<<16 DMA_PUMP ; or @DMA_XINT,IE ; enable transmit int ldi DMA_STOP,R0 ; stop and reset DMA sti R0,@DMA_ctrl ; ldi 0,R0 ; sti R0,@DMA_xfr ; ldi @DMA_SRCE,R0 ; sti R0,@DMA_srce ; ldi @DMA_DEST,R0 ; sti R0,@DMA_dest ; ldi DMA_RUN,R0 ; sti R0,@DMA_ctrl ; rets ;------------------------------- poll_xint tstb XINT,IF ; bz $-1 ; andn XINT,IF ; rets ; prog_AIC ldi @S0_xdata,R1 ; Use original DXR data during 2 ndy sti R1,@S0_xdata ; call poll_xint ldi @S0_xdata,R1 ; Use original DXR data during 2 ndy or 3,R1 ; Request 2 ndy XMIT sti R1,@S0_xdata ; call poll_xint sti R0,@S0_xdata ; Send register value call poll_xint andn 3,R1 ; sti R1,@S0_xdata ; Leave with original safe value in DXR ;--------------------- ldi @S0_rdata,R0 ; Fix the receiver underrun by reading rets ; the DRR before going to the main loop stack .word $+1 ;****************************************************; ; Install the XINT/RINT ISR handler directly into ; ; the vector RAM location it will be used in ; ;****************************************************; .start "SP0VECTS",0x809FC5 .sect "SP0VECTS" b DAC2 ; XINT0 b ADC2 ; RINT0 +-----------+ |Keith Larson | |Member Group Technical Staff | |Texas Instruments Incorporated | | | | 281-274-3288 | | | | www.micro.ti.com/~klarson | |-----------+ | TMS320C3x/C4x/VC33 Applications | | | | TMS320VC33 | | The lowest cost and lowest power 500 uw/mflop | | floating point DSP on the planet! | +-----------+ |