                         -----------------------
                            A BEGINNERS GUIDE
                         TIPS, TRICKS, AND TRAPS
                                 VOL 1
                         -----------------------
         VOLUME 1 (THIS)
         --------
         ANALOG SIGNALS
         INT2 STARTUP AND COMMUNICATIONS
         HOW THE DEBUGGER WORKS
         TYPICAL ERRORS
         EFFICIENT USE OF INTERNAL SRAM
         WRITING FAST CODE
         ADD ON DAUGHTER CARDS
         PAL DECODED SIGNALS
         EXTERNAL BOOT ROMS
         EEPROM LOADER UTILITY
         EXTERNAL SRAM
         EXTERNAL IO DEVICES
         SERIAL TO PARALLEL CIRCUIT
         ANALOG CIRCUITS
         MULTITASKING APPLICATIONS
         BLINKING LED (PWM DRIVER)

         VOLUME 2
         --------
         SUPER SCHMIDT HYSTERESIS
         PG6 EXTENDED OPCODES
         HOW TO DETERMINE SILICON VERSIONS
         CONVERTING TMS320 FLOATING POINT TOOLS CODE
         WHY A TMS320C31 INSTEAD OF A TMS320C32
         WHY USE A PARALLEL INTERFACE?
         PROJECT IDEAS (NEAT TRICKS)
         STUPID DSK TRICKS
         SFFT.ASM
         BENCHMARKING
         SUPER FAST 4 CYCLE SQUARE ROOTS
         PORTING TO C32 TARGET
         SVGA GRAPHICS

    ANALOG SIGNALS
    --------------
      ADC input   +/- 6 Vdc maximum with respect to ground.
      DAC output  +/- 3 Vdc with no load
      SAMPLING    14 bits ADC/DAC at 20 KHz (higher rates degrade performance)

      Input overvoltage protection is provided by 470 ohm series limiting
      resistors in both AIN and AOUT.  This protection is NOT foolproof,
      so do not connect the DSK to higher voltages than are specified.

      Earphones will provide adequate signal level to hear the DSK output
      especially if the input impedance is relatively high.  For example, a
      good set of cheap 'ear-bud' style headphones made by Koss can be
      purchased from Wal-Mart for around $5 US.  Sony headphones run about
      $10 but have a lower impedance.  All that is then required is an 1/8\"
      stereo to RCA adapter.  For best results, the adapter should connect
      the earphones in series, further increasing the impedance.

      NOTE: The 470 ohms series limiting resistor will cause a peak in the
      response at the impedance peak of the earphones.  With a simple wire
      loopback, you can probably write a program to measure this peak.  A
      good 'simple' starting point would be to modify the FFT analyzer to
      generate a white noise level instead of the ramp test signal.  Note
      that the software loopback will not work in this case since this
      loopback samples the DAC signal on the DAC side of the 470 ohm resistor.

    INT2 STARTUP AND COMMUNICATIONS
    -------------------------------
      Since the DSK must communicate with the host for debugging and data
    transfers, you cant just turn off the interrupts and expect the DSK
    to work.  Essentially the DSK uses the TMS320C31 INT2 line to

      1) Initiate the proper bootload mode after reset (INT2 EPROM boot).

      2) Signal that a communications is being requested (strobe line low).

      After reset, asserting INT2 selects an EPROM bootload the external bus
    beginning at address 0xF00000.  A /READY control circuit in the PAL22V10
    is then used to pulse /READY with the rising edge of the printer port
    strobe line.   If the data byte is valid when the /READY is pulsed the
    DSP will momentarily unfreeze and read the data.  You can think of each
    external read from the boot address range as having an a permanent wait
    state condition interrupted by the rising edge of the printer strobe.

      When the boot process is completed, the CPU begins executing the kernel
    that was just downloaded.  The kernel then configures the INT2 line as
    an interrupt which is used to indicate a host communications request.

    HOW THE DEBUGGER WORKS
    ----------------------
      As explained earlier, INT2 is used to indicate that the host has dropped
    the printers strobe line, usually to indicate that a kernel command is
    being requested. (See the DSK Users Guide for more detailed information).
    If the INT2 interrupt is disabled (0x4 is not set the IE register), the
    DSP has no way to tell that a communications request is under way.  In
    your applications code you can also poll this bit.

      The singlestep operation uses a technique where an interrupt is set in
    the IF register but not enabled until one cycle of the users code has been
    fetched and decoded.  This is done by enabling the global interrupt bit
    during a delayed return from the DSK command mode.  A function step is
    nearly identical except that when a CALL is detected a breakpoint is
    set immediately after the call and the DSK is placed in a free run state
    to execute up to the breakpoint.

      Note: Singlestepping with this techniques allows ALL breakpoints to
            be removed while the device is being singlestepped.  This has
            some interesting, and often beneficial side effects that will
            be explained later.

      The interrupt used for singlestepping is actually a leftover from the
    TMS320C30 device which the TMS320C31 was derived from.  The TMS320C30 had
    two serial ports and the TMS320C31 only one.  Luckily the interrupt control
    bits for this device were left intact when that peripheral was removed
    from the core.

      Since the interrupt used for singlestepping has a relatively low
    priority it is possible to cause that interrupt to be lost or delayed
    during a singlestep operation where the IE or IF registers are being
    directly modified.

      In general if the SSTEP interrupt is cleared by a  higher level interrupt
    the singlestep operation will fail and the DSK will enter the run free
    state.  If the debugger detects that the singlestep operation was not
    succesful, it will assert the INT2 line and try to reaquire aquisistion
    of the DSK communications link.  If this fails, there is no way to recover
    the application until it is re-loaded.

      If in either case the singlestep operation fails a message will be
    displayed on the debugger command line telling the user that there is yet
    another option.  The 'super step' option is enabled by pressing the shift
    key while singlestepping or function stepping.  The super-step option
    temporarily swaps all of the interrupt branch instructions with branches
    to the singlestep routine thereby eliminating the possability that any
    higher level interrupt can preempt the singlestep function.  After the
    singlestep is completed, the interrupt branch table is restored.

      The advantage of not swapping out all of the interrupts and or always
    setting trap codes is that the DSP can process higher level interrupts
    while still allowing the singlestep.

      Setting a breakpoint within a interrupt routine will also work, but
    there are some side effects.

      - If you singlestep the ISR, and the ISR bit is reset during the
        time between user keystrokes (likely), the ISR interrupt will nest.
        You can easily detect this by the watching the SP register which will
        increment each time you single step.  You can stop this from happening
        by disabling the interrupt by clearing the IE enable bit, or globaly
        clearing all interrupts.  If you clear all breakpoint and free run
        the DSP the nesting will usualy un-nest with no side effects.

      - You can step through the bootrom, which may be very useful for an
        EPROM bootload daughtercard.  However, you will need to interact
        with the CPU to jump past certain lines of code.  For example, there
        is a line of code that sets the stack pointer value.  Since changing
        the stack pointer will esentially cause the debugger to loose track
        of its own code, you will need to jump past this code by telling the
        debugger to increment the PC value (PC=PC+2 for example).  Another
        trouble spot is when the IF bits are tested.  In this case the kernel
        code clears these bits and the conditinal branch will not occur.
        Other than this you can singlestep the ROM, but you cannot set a
        breakpoint since the debugger cannot swap out a ROM coded instruction
        for a breakpoint trap.

    TYPICAL ERRORS
    --------------
    - Do not overwrite the DSK kernel which is located in the last 256
      words of on chip SRAM with code, data or stack.

    - Be sure not to accidentally overwrite the kernel if you modify the
      interrupt branch table which is located in the communications kernel
      area.

    - The DSK uses INT2 and XINT1 for communications and debug emulation.
      Disabling these interrupts can cause the debugger or applications
      to fail.  The following may be helpful in managing the interrupts.

      OR    1,IE     ; Sets only INT0
      ANDN  1,IE     ; Clears only INT0
      OR    0C4h,IE  ; Re-enable SSTEP and Host
      RETI           ; interrupts before returning

      NOTE:
      In some cases, such as programming the AIC, it may be neccesary
      to disable all other interrupts to ensure critical timing loops.
      Be sure to re-enable the host interrupts when finished.

    - Programming the AIC requires that a pair of words be sent to the
      TLC32040 in consecutive frames.  If you single step the AIC
      initialization code the secondary word can be corrupted and the
      AIC will be non functional.

    - To prevent accidentally reprogramming the AIC when the serial port
      restarts during debugging, the value 0000h is loaded into the data
      transmit register when the TMS320C31 is stopped.  When the serial
      port restarts, the last sent value is sent to the AIC shifted by a
      random number of bits.  Since any value other than zero can reprogram
      the AIC the DXR is pre loaded with zero in anticipation of a restart

    EFFICIENT USE OF INTERNAL SRAM
    ------------------------------

      A lot of applications can be fit directly into the on chip memory of
      the TMS320C31.  Here are some examples of how to better use and
      preserve the on-chip resources.

      Initialization stubs
      --------------------
      If you have initialization code or data that is used only during
      startup you can quite often reuse the same memory locations for
      for volatile data or stack space.  However, be careful to note that
      if you try to debug this code, the debugger stack can in fact
      grow into the initialization code or data, corrupting the runtime
      environment.

      Stack Pointers
      --------------
      You can also hide the

      Faster returns from nested calls
      --------------------------------
      If you see a CALL to a function followed immediately by a RETS, you
      can replace the CALL with a branch to the function and use the called
      functions return to pop back to the original caller.  This saves one
      line of code and 8 executions cycles (CALL and RETS eliminated).

         ;-------------------------------------------;
         ; Sample program for CALL/RETS optimization ;
         ;-------------------------------------------;
                .start    \"Test\",0x809802; Start section here
                .sect     \"Test\"         ; Use section
                .entry    Main           ; Begin execution at 'Main'
         ;-------------------------------
         Main   call      FUNCA          ; Call function (push Main+1)
                b         Main           ; Do it again
         ;-------------------------------
         FUNCA  addi      1,R0           ;
              ; call      FUNC           ; Old code used CALL/RETS
              ; rets                     ;
                b         FUNC           ; Optimized CALL/RETS uses FUNC rets
         ;-------------------------------
         FUNC   addi      1,R0           ; Nested function
                rets                     ; return to Main+1 (optimized)
                .end                     ;

      Reusing common returns
      ----------------------
      Quite often you will find that some functions use the same exit code.
      By replacing this with a branch to a common piece of code a substantial
      savings in code space can be realized.  Furthermore, if the common
      routine is attached to the end of one function, the branch for that
      routine can be eliminated.  Note that this is rather slow, so dont
      use this where speed is important.

      ;----------------------------
      FuncA      push  R0          ;
                 push  R1          ;
                 push  R2          ;
                  :    :           ; Code for FuncA
                 b     PopAllInt   ;
      ;----------------------------
      FuncB      push  R0          ;
                 push  R1          ;
                 push  R2          ;
                  :    :           ; Code for FuncA
               ; b     PopAllInt   ; PopRegs follows, no need to branch!
                 ;-----------------
      PopRegs    pop   R2          ; Common return uses 4 opcode locations
                 pop   R1          ;
                 pop   R0          ; In this case, savings is 2*4-1=7 words
                 rets              ;

      Other variations of this technique can be used to replace the context
      save 'push' opcodes with common routines, but this gets a little
      trickier since the call stack is now involved.

      2^N Looping
      -----------
      The following code fragment shows how to loop a subroutine 2^N
      times depending on the number of 'CALL $+1' statements.  Each
      CALL essentially pushes the next address onto the return stack
      which is then used to pop and branch back to the subroutine 2^N
      times until finaly the final return is popped.  This can also be
      used for a long delay.

      ;=========================================================
      Begin  ldi    0,R0   ; Init R0=R1=0
             ldi    0,R1   ;
             call   N8     ; Returns R0=8, R1=-8
             b      Begin  ;
      ;--------------------
      N8     call   $+1    ; call/push next address (N4)
      N4     call   $+1    ; call/push next address (N2)
      N2     call   $+1    ; call/push next address (N1)
      N1     addi   1,R0   ;
             subi   1,R1   ;
             rets          ; return pops to N1, N2, N4....
      ;=========================================================

      Super NOP
      ---------
      A branch to the next location (B $+1) will take 4 cycles compared
      to a NOP which takes only 1 cycle.

      Preserving the loop count
      -------------------------
      In some applications, such as MANDEL3X.EXE, it may be desirable to
      know the loop count when a condition indicates that the loop should
      be broken.  In this case the repeat block is exited by writing zero
      to the repeat end register.  Since the code is never going to execute
      at address zero (the reset vector!) the code block effectively exits
      with the repeat counter intact.  This eliminated the need for a
      register counter within the repeat block.

    norm     rptb     block        ;
             ;---------------------
             MPYF3    R3,R3,R5     ; R^2 = R*R;
             MPYF3    R4,R4,R6     ; I^2 = I*I;
             MPYF     2.0,R3       ; I   = 2.0*R*I + Iseed;
             MPYF     R3,R4        ;
             ADDF     R2,R4        ;
             SUBF3    R6,R5,R3     ; R = R^2 - I^2 + Rseed;
             ADDF     R1,R3        ;
             ADDF3    R6,R5,R5     ; if((R^2+I^2) > 4.0) break;
             cmpf     4.0,R5       ;
    block:   ldige    0,RE         ; Fast loop exit, with RC intact
    M_exit   subi     RC,R0        ; get loop count
             and      0xff,R0      ; return color (mod 256)

    WRITING FAST CODE
    -----------------
      Internal SRAM
      -------------
      Each internal SRAM block (RAM0 and RAM1) can support two data access' or
      one program access per CPU cycle.  This means that if you code and data
      are both in the same ram block, you will not see optimal code efficiency.
      In general you will want to have your code and data in seperate SRAM
      blocks.

      Cache
      -----
      When an opcode is loaded into the cache it effectievly appears to be
      contained in a third internal SRAM.  Since this frees both internal
      SRAMs for DMA and data moves, performance will increase.  However, the
      cache cannot be loaded from internal memory.  For the cache to load the
      code must be fetched from external memory.

      Posted writes
      -------------
      When the C31 writes data to a bus, the first data write is 'latched'
      into the bus control logic, mcuh like a 1 level deep write cache.  This
      allows the CPU to continue execution internaly while a write is still
      in progress.  However, if a second write occurs before the first one is
      complete, the CPU is stalled pending a write access to the bus.  By
      spreading out your writes to the external bus, you can have a vary
      slow external bus and see no speed degradation.

      Note however, must also wait for reads

      ;-------------------------------------------------------;
      ; Assume external bus software wait states are set to 7 ;
      ; This loop executes in 18 cycles                       ;
      ;-------------------------------------------------------;
    Begin ldi    @XBus,AR0 ; AR0 = external address
    loop  sti    R0,*AR0   ; Post 1st write (2+7=9 cycles)
      ||  sti    R1,*AR0   ; Post 2nd write (2+7=9 cycles)
          b      loop      ; (the branch is an internal operation)

      ;-------------------------------------------------------;
      ; Assume external bus software wait states are set to 7 ;
      ; This loop also excutes in 18 cycles                   ;
      ;-------------------------------------------------------;
    Begin ldi    @XBus,AR0 ; AR0 = external address
    loop  sti    R0,*AR0   ; Post 1st write (2+7=9 cycles)
          nop              ;
          nop              ;
          nop              ; Execute up to 8 internal operations
          nop              ; with no conflict.  Runs at the same
          nop              ; speed
          nop              ;
          nop              ;
          nop              ;
          sti    R1,*AR0   ; Post 2nd write (2+7=9 cycles)
          nop              ;
          nop              ;
          nop              ; Execute another 8 internal operations
          nop              ;
          B      loop      ; (branch consumes 4 cycles)

      RPTS Repeat single
      ------------------
      An interesting aspect to the RPTS instruction is that the code that is
      repeated is feteched from memory one time and then kept internal to
      the pipeline.  This frees the buses from code fetch operations, and
      therefor helpful.  For example, using the RPTS you can have code and
      data located in the same internal SRAM block with no speed penalty.

    ADD ON DAUGHTER CARDS
    ---------------------
      You should connect the DSK to an add on card using 0.100 spaced male
      and female headers that are common in PC board interconnects.  The
      posts are typically 0.025 square.

      The female connectors should be used on the DSK since these connectors
      cost more and will also keep the underside signals from shorting when
      your daughtercard is not connected.  Also, the female connectors act
      as standoffs for the DSK when it is not connected to the daughtercard.
      Using male connectors on the DSK side is NOT advisable since the male
      pins are easy to short or bend.

      The best prototype circuit board material will have a solid a ground
      plane on one side and solder pads on the other.  A plated through hole
      will offer the best mechanical connection, but will cost more and you
      need to be carefule that on the ground plane side, the pad on that
      side does not unintentionaly become electrically connected to the
      ground plane.

      A solid ground plane provides an excellent ground that is easy also
      easy to connect to without using a ground bus.  All you need to do is
      pass a wire from the solder connection to the ground side and solder
      it to the plane.

      Solder side interconnects can be either point to point (best signals)
      or between wire wrap pins.

      Point to point connections are easily made with wire wrap wire and a
      soldering iron.  Start by stripping off a section of insulation to
      expose some wire and then cut the wire back till there is only a very
      short piece of exposed wire.  If you then heat the solder joint till
      it melts, you can then poke the wire into the molten lead.  When the
      joint cools you will have a neat, clean and low profile connection.

      Connecting the other end can be done the same way, but there are
      some methods that can produce even nicer results.  For example if you
      solder down one end of the wire and then pull it through an adjacent
      PWB hole to the ground plane side you can use the PWB holes to neatly
      run wires around the board.  When you get to the destination hole,
      you can push the wire back through an adjacent hole and if the stripper
      you are using has the right clearance you can feed the wire through
      with the stripper blades close to the PWB.   I use a rather old
      'OK Industries' all in one manual wire wrap tool.  By then pullng up
      on the stripper you get a perfect length of insulation.  You then heat
      the solder joint and twist the wire onto the socket post by about
      1/3-1/2 turn.  Then cut off the excess bare wire.

      Note: You may want to try these techniques on a scrap board before
      committing to a full up daughtercard.  Also, if you use sockets it
      will be much easier to rework an IC since you would have to remove
      the entire IC if you made a mistake.

      Remmeber to leave at 2-3 open holes on the outside edges of the add
      on cards JPx connections to the DSK.  These open holes will be
      important when you try to route the many wires required to connect
      to them.

      If you need to connect several byte or integer wide devices to the
      data bus, you can connect them to any consecutive data pins and then
      use software in your application code to mask off and shift the bits
      you are interested in..

      With practice, 3 or more wires can be connected to a single solder
      joint if they are not physically too close to other solder joints.
      The data and address buses are dificult to add several wire to since
      they are packed into 2 x 16 headers.

    PAL DECODED SIGNALS
    -------------------

      The PAL22V10Z which is used for the host port interface has also been
    configured to generate several useful strobe signals for building
    external circuits.  Typical current consumption for high speed PALS is
    often 130 mA or more.  The PAL22V10Z typicaly consumes 80 mA of current,
    and when clocked at a lower rate, is far less.  With the DSP in lowpower
    mode, the PAL consumes <10 mA, and when stopped in IDLE2 the current is
    only 10-20 uA.

                                A23                   A0  R/W
     Host port, interlock      1111 xxxx xxxx xxxx xxxx  x  0xF0000-0xFFFFF
     Host port, non interlock  1110 xxxx xxxx xxxx xxxx  x  0xE0000-0xEFFFF
     USERR                     110x xxxx xxxx xxxx xxxx  0  0xC0000-0xDFFFF
     USERW                     110x xxxx xxxx xxxx xxxx  1  0xC0000-0xDFFFF
     USERX                     110x xxxx xxxx xxxx xxxx  x  0xC0000-0xDFFFF
     SRAM                      10xx xxxx xxxx xxxx xxxx  x  0x80000-0xBFFFF
     No Decode                 0??? xxxx xxxx xxxx xxxx  x  0x10000-0x7FFFF
     UBOOT                     0000 xxxx xxxx xxxx xxxx  x  0x00000-0x0FFFF

     A23=0 and /STRB           0xxx xxxx xxxx xxxx xxxx  x  0x00000-0x7FFFF
     enabled SRAM              (note conflicts with UBOOT)

      Again, for a wire wrap daughter card, 1WS may still be needed for
    reliable operation.  The host port needs 1WS (usualy works with 0),  so
    by the numbers, /SRAM with 1 WS is the simplest most reliable solution.

    EXTERNAL BOOT EPROMS
    --------------------
      An external boot EPROM or EEPROM can be added to the DSK by using the
      /UBOOT enable pin to enable a device in the range of 0x000000 to
      0x100000 which corresponds to a bootload select using INT0.

      The TMS320C31 bootloader is actually DSP code that is contained in a
      pre-programmed ROM internal to the chip.  The internal bootloader code
      space is mapped to 0x0000-0xFFFF and is enabled by MCBL/MP=1, which is
      the default for the DSK.  The internal bootloader is used for normal
      DSK operation as well as EPROM bootloading so there is no need to
      change the value of MCBL/MP.

      When an INT0 bootload is selected, the internal bootloader code causes
      the DSP to read the first external byte value (the code you want to
      bootload) from address 0x1000.  Other interrupts select different
      address ranges.  For example, INT2 which the DSK used for host
      communications is also used to bootload the DSK kernel from the host
      interface.

      If your EPROM decodes an address range less than 0x1000, you can use
      memory aliasing to access your bootcode at ROM_address=0x0000.  You
      can do this with a larger EPROM by tying the upper EPROM address lines
      low, but this wastes EPROM space.  Memory aliasing works because the
      external ROM is enabled over many pages, one of which is at 0x1000.

      If your EPROM decode range is greater than 0x1000, you will need to
      copy/load your bootcode at an offset of 0x1000 in the EPROM.  The
      lower 0x1000 of space can still be accessed using an aliased memory
      page.

      The number of software wait states defined in the bus control register
      must be sufficient for the speed of the EPROM that you use plus the
      delay time for the /UBOOT signal to decode.  For example, if you use
      an 85 nS EPROM, and the decoder takes 25 nS, plus DSP signal delay of
      13 nS, You will need 123 nS of bus cycle time.  With three wait states
      the bus read time is (3+1)*40 nS = 160 nS which ensures proper operation.
      In practice, if the devices are operated at or near room temperature,
      which widens the timing margins substantially, fewer cycles may work,
      but it is not suggested.

      The DSK host interface also requires at least one wait state to operate
      properly.  Do not lower the wait states below this value if you plan to
      also use the DSK debugger.  Since DSK bootloaded code primarily runs
      in the on-chip memory, any value of wait states will work without
      degrading performance.

      The DSK3D debugger can be used even if an external EPROM is used.  The
      only constraint is that the first bootloader select interrupt after
      reset is applied will determine which bootsource will be used.

      If the printer port is not connected, or if the DSK debugger (or other
      application) is not executing a command, the INT2 line will be inactive
      high.  By then pulsing /RESET low, followed by INT0 low, the TMS320C31
      will execute a bootload operation from address 0x1000.

      Typical (E)EPROM circuit
      ------------------------
        DSK HEADERS          8 bit (E)EPROM
                       Vcc
                        |
            JP6         Rp   +------------+
            +--+  #J1   |    |            |
      /UBOOT| 4|---x-x--*----|/CE         | #Jumpers J1 & J2 are either
            |  |  #J2        |            |  both installed or both removed
         PWM| 9|---x-x--+    |            |
            +--+        |    |            | *A R/W connection is only
                       ///   |            |  needed for an EEPROM
            JP3        Gnd   |            |
            +--+             |            |  Other chip enables may need
          A0|32|-------------|A0          |  be tied to logic high or low
          A1|31|-------------|A1          |
           .| .|-------------| .          |
          AN|??|-------------|AN (size?)  |
            +--+             |            |
            JP5              |            |
            +--+             |            |
          D0|32|-------------|D0          |
          D1|31|-------------|D1          |
           .| .|-------------| .          |
          D7|25|-------------|D7          |
            +--+        Vcc  |            |
                        |    |            |
            JP2         Rp   |            |
            +--+  *J3   |    |            |
         R/W|21|---x-x--*----|R/W (EEPROM)|
            |  |             |            |
            |  |             +------------+
       RESET|20|---+
            +--+   |
                     |
                     |--- SW1 (user reset)
                     |
                   |
                  ///
      NOTES
      -----
      - Use 0.10 spacing female connectors on the bottom of the DSK.  Dont
        put the female connectors on the add on card.  The female connectors
        cost more than the male connectors and make excellent board standoffs
        when a daughtercard is not connected.

      - Double check your work before applying power.

      - Before you apply power, first start the debugger from the OS command
        line.  The debugger will continuously try to start, waiting for the
        power to be applied.

      - Change the Memory window start address to 0x1000 using the command
        'MEM 0x1000'.  You will then see the contents of the EPROM (in the
        lower bytes) if it is working properly.  If you are using an EEPROM, or
        have not pre-programmed the EPROM, the contents may be all 1's, 0's or
        random.  If you re-issue the MEM 0x1000 command, these bits should not
        change.  If you then scroll the memory window below 0x1000 the values
        should move in the window, staying with the original address.  The
        values below 0x1000 will be the last few words of the on-chip
        bootloader which is aliased into 256 word boundaries.

      - Since the PWM LED mode can also select the EPROM, you need to be sure
        that you have disabled the PWM or DEMO mode.  As shown two jumpers are
        used for both the PWM mode and EPROM enable.  Either both are installed
        or both are removed.

      - The short circuit driver current of each of the TMS320C31's pins is
        quite high, typicaly driving +150/-400 mA to the supply rails.  This
        current can produce as much as 0.400 A x 5.0 V = 2.0 Watts of heat
        dissapation which can easily damage the TMS320C31.

        These large currents are never seen in actual operation, but are
        required to be able to switch heavily capacitive loads with fast
        slew time.  For example, to drive an 80 pF load with a 3 nS rise
        time between the valid logic levels an average current of 60 mA is
        required per pin.  In practice this current is only present for the
        short period of time that the signal is slewing from one rail to the
        other, or 3 nS out of the 40 nS cycle time.  You can calculate the
        required driver current using the equation I=C*dV/dT.

      - If you use an EEPROM, the DSP can write data to the EPROM.  However
        since the write algorithms vary in the industry, you will need to
        write a special routine that runs on the DSP to perform the copy
        process, or use a program running on the host to write and verify
        the EEPROM using the putmem() and getmem() functions.  A good place
        to start would be the sample program 'SIMPLE.CPP'.

      - If the total DSK current consumption causes the regulator to run
        abnormaly hot you should heatsink the regulator and or lower the
        supply voltage

      - As shown the reset switch circuit does NOT provide hysteresis.  You may
        need to press the switch more than once to boot the EPROM, but for most
        applications this is sufficient. Also note that this does not conflict
        with the host reset since the INIT line is resistor isolated. You can
        write a simple PC based utility to pulse the printer ports INIT line.

    EEPROM LOADER UTILITY
    ---------------------
        An EEPROM loader utility has also been written.  However, at this time
        an test board was NOT available to try this utility with :(  This
        application simply reads a *.HEX file, which contains a bootable
        code image, and copies it into a destination address one byte at a
        time.  You have the option of specifying the file name, where to load
        the file to, adjustable write rate, and a memory window to see the
        results.  The source code is also included if you wish to add more
        features.

    EXTERNAL SRAM
    -------------
      You can connect an external SRAM in much the same way as an external
      EPROM.  The only difference is that you will need to connect more data
      pins and you do not need to work around the PWM mode since the /SRAM
      enable pin is always active.

      Typical SRAM circuit using PAL /SRAM enable (1 WS operation)
      -------------------------------------------
          DSK HEADERS         32 bit SRAM

            JP6              +------------+
            +--+             |            |
       /SRAM|14|-------------|/CE         | Other chip enables may need to
            +--+             |            | be tied to logic high or low
            JP3              |            |
            +--+             |            |
          AN|??|-------------|AN 2^N      | ********************************
          A2|30|-------------|A2 word SRAM| * >>>>>>>>  IMPORTANT <<<<<<<< *
          A1|31|-------------|A1          | *   1 WS IS REQUIRED FOR THE   *
          A0|32|-------------|A0          | *  HOST PORT TO WORK PROPERLY  *
            +--+             |            | ********************************
            JP5              |            |
            +--+             |            |
          D0|32|-------------|D0          |
          D1|31|-------------|D1          |
           .| .|-------------| .          |
         D31| 1|-------------|D31         |
            +--+             |            |
            JP2              |            |
            +--+             |            |
         R/W|21|-------------|/WE         |
            +--+             +------------+

      SRAM devices can also be and /CE can be effectively used for faster
      external decode (no PAL).  In this a fast external decoder combines
      /STRB, A23 and A22 in the same decode as the PAL.  Note that some
      SRAMs may have other enable lines that can be used to create this
      decode internal to the SRAM for even better performance.
      --------------------------------------------------------------

          DSK HEADERS         32 bit SRAM
            JP2              +------------+
            +--+             |            |
         R/W|21|-------------|/WE         |
       /STRB|22|--+          |            |
            +--+  |          |            |
            JP3   |          |            |
            +--+  --+---\\    |            |
         A23| 9|---O|   |----|/CE         | Other chip enables may need to
         A22|10|----+---/    |            | be tied to logic high or low
            |  |             |            |
          AN|??|-------------|AN 2^N      | ********************************
          A2|30|-------------|A2 word SRAM| * >>>>>>>>  IMPORTANT <<<<<<<< *
          A1|31|-------------|A1          | *   1 WS IS REQUIRED FOR THE   *
          A0|32|-------------|A0          | *  HOST PORT TO WORK PROPERLY  *
            +--+             |            | ********************************
            JP5              |            |
            +--+             |            |
          D0|32|-------------|D0          |
          D1|31|-------------|D1          |
           .| .|-------------| .          |
         D31| 1|-------------|D31         |
            +--+             +------------+

      Notes
      -----
      - See the EEPROM notes, they will be helpful!

      - The memory decode range for /SRAM begins at 0x800000, which is
        internal.  The first external address begins just after the on-chip
        RAM blocks at 0x80A000

      - As shown the memory is being write enabled using the /CE technique.
        Many SRAMs support this mode but may not enter low power mode.

      - If the total DSK power consumption causes the regulator to run hot
        you should heatsink the regulator and or lower the supply voltage

      - 1 wait state access will be required if you run the C31 at
        full speed and still use the PAL22V10 /SRAM pin for decode.

      - If you use an external decoder, be sure to allow a few extra nS for
        the signals to become stable on the daughter card.  When the signals
        are routed this way they will exhibit some delay and signal ringing
        that must be accounted for in the design.

    EXTERNAL IO DEVICES
    -------------------
        Similar to EEPROM and SRAM, the DSK also has a section of the memory
        map decoded for IO devices.  These signals are activated when the
        Address range, bus strobe enable, and R/W are active as shown.

        USERX  Read or Write  0xC00000-0xDFFFFF
        USERR  Read           0xC00000-0xDFFFFF
        USERW  Write          0xC00000-0xDFFFFF

        Output circuit
        --------------
                    +-----+            *Freeze or latch output data on
        /USERW ---->|>CLK |             rising edge of /USERW
            D0 <----|D0 Q0|-----<
            D1 <----|     |-----<
            D2 <----|     |-----<
            D3 <----|     |-----<
            D4 <----|     |-----<
            D5 <----|     |-----<
            D6 <----|     |-----<
            D7 <----|D7 Q7|-----<
                    +-----+

           74HC374 latch, Parallel DAC with latch, PAL22V10...

        Input circuit
        -------------
                    +-----+          *Enable input data while /USERR is
        /USERR --+->|/EN  |           low, and clock any new data into
                 +->|/CLK |           the peripheral.  EG a flash ADC
                    |     |
            D0 <----|D0 Q0|-----<
            D1 <----|     |-----<
            D2 <----|     |-----<
            D3 <----|     |-----<
            D4 <----|     |-----<
            D5 <----|     |-----<
            D6 <----|     |-----<
            D7 <----|D7 Q7|-----<
                    +-----+

          74HC245 buffer, TLC5510 8 bit Flash ADC, PAL22V10 etc...

    SERIAL TO PARALLEL CIRCUIT
    --------------------------
      Another useful method for creating a parallel output bus is to use a
      serial to parallel converter.

      In the example shown below two PAL22V10 devices are used.  PAL U1 is
      used as the serial to parallel converter and PAL U2 is used as a latch
      freeze the parallel data on the rising edge of FSX.

      The serial port transmit channel is configured with FSX as an output,
      variable burst mode, with all polarities positive.

      FSX  ----------------+
                U1         |  U2
                +-------+  |  +-------+
      CLKX -----|>CLK   |  +--|>CLK   |
      DX   -----|D0   Q0|-----|D0   Q0|--- D0
                |     Q1|-----|D1   Q1|--- D1
                |     Q2|-----|D2   Q2|--- D2
                |     Q3|-----|D3   Q3|--- D3
                |     Q4|-----|D4   Q4|--- D4
                |     Q5|-----|D5   Q5|--- D5
                |     Q6|-----|D6   Q6|--- D6
                |     Q7|-----|D7   Q7|--- D7
                |     Q8|-----|D8   Q8|--- D8
                |     Q9|-----|D9   Q9|--- D9
                +-------+     +-------+

       Equations
       U1           U2
       --------     --------
       Q0 := D0     Q0 := D0    ** The ':=' operator signifies that the
       Q1 := Q0     Q1 := D1       input equation is latched into the
       Q2 := Q1     Q2 := D2       output on the rising edge of the
       Q3 := Q2     Q3 := D3       PAL22V10 CLK in
       Q4 := Q3     Q4 := D4
       Q5 := Q4     Q5 := D5
       Q6 := Q5     Q6 := D6
       Q7 := Q6     Q7 := D7
       Q8 := D8     Q8 := D8
       Q9 := Q9     Q9 := D9

    ANALOG CIRCUITS
    ---------------

      DISTORTED SIGNAL IN AIC DATA (ie LOOPBACK fails)
      ------------------------------------------------

      -The serial port does NOT sign extend the data that it receives.  Sign
       extend by left shifting 16 bits, followed by arithmetic right shifting
       by 16 bits.

      -If a sample delay is tolerable, you can use the older sample, which is
       in the upper 16 bits, by simply arithmetic right shifting by 16 bits.

      -NOTE: Early versions of 'LOOPAIC.ASM' scaled the ADC values by 16
       before looping them back to the DAC.  If the sampling rate and timers
       were set to beyond 20Khz sampling, significant distortion could be
       heard since the noise floor was essentialy 16x normal.  'LOOPAIC.ASM'
       was modified to have a software setable nominal gain of 1.  If you
       want to change the gain look for the 'GAIN' variable in the source code.

      SERIAL PORT
      -----------
        When the serial port is not updated for each frame synch it will enter
        a shutdown mode until the DXR and DRR registers are again accessed.

        However, when these registers are again accessed, the data in them can
        be corrupted.  For the AIC ADC, this will only mean that a data glitch
        will occur, but for the transmitter this is more serious since the
        outgoing glitch can also reprogram the AIC.  The transmit glitch occurs
        because the DXR, which is empty, is loaded directly from the DXR to
        the transmit shift register when the DXR is loaded.  Since the state
        of the frame synch may be active at the time this occurs any other
        value besides zero can send an erroneous bit to the AIC causing it
        to enter its programming or secondary transmit mode.

        To ensure safe stopping and re-starting of the AIC it is recommended
        that the DXR be loaded with zero whenever it is about to be stopped
        for an extended period of time and then reloaded with zero when the
        extended time period is to be terminated.

      THE AIC
      -------
        The DSK circuit board is designed to provide maximum flexability
        in prototyping new applications.  The AIC that is used provides
        the following characteristics that are not commonly found in an
        audio band device.

          - 14 bit ADC/DAC at 20 KHz sample rate
          - Defeatable band-pass anti-aliasing filter
          - Fast sample and hold with >>100 Khz aperature bandwidth
          - Sample by Sample conversion provides low latency

        The ADC/DAC precision degrades as the sampling rate is increased.
        The amount of degradation is dependent on the AIC divisor registers
        and will typicaly provide 12 bit accuracy at 40-50 Khz.  If you are
        willing to live with even more degradation, the AIC will continue
        to operate to above 100 KHz.

        The defeatable band-pass anti-aliasing filter is especially important
        in applications where fast rise times and low latencies from the time
        of conversion to the time that the software sees the data are
        important.

        A good experiment is to connect a square or triangle wave  signal to
        the input and look at the response using the oscilliscope program.
        Here you will see that the sample and  hold 'aperature' has
        sufficient bandwidth to achieve clean square edges.

        A similar experiment is to view the signal in the frequency domain
        using one of the FFT analyzers.  In this case you can input sinewaves
        increasing the frequency up to nearly 1 MHz before the signal begins
        to show any rolloff.  This particular ability can be quite usefull in
        downconverting high frequency signals straight into the baseband.
        For example you could use these techniques to demodulate an AM or FM
        radios I/F signal into listenable audio.

        A Ground and Vcc planes around the AIC are cut out from the digital
        planes to isolate the digital noise from the sensitive analog
        conversion process.  You can hold the board up to a light and see
        where the divisions are physically located.

        A single connection, or isolation circuit is then used to connect the
        cut out plane to the larger digital plane.  For the ground, the
        connection is a zero ohm resistor and for the +/-V a 10 ohm resistor
        is used as a simple RC filter.  The result is that the ADC conversion
        is clean to 14 bits of accuracy even when the input bandwidth is
        unrestricted, essentially to 1 MHz.

        An analogy that may help is that the digital noise is like having
        large waves in a lake, while a smaller analog pond is connected
        by a small stream.  The large waves cannot get through.

        OTHER ANALOG CIRCUITS/ OP-AMPS, ADC/DAC's ETC...
        ------------------------------------------------
        Typically a solid ground on an external PWB will have a fairly low
        noise level and since the ground is 'common' to all signals is usualy
        immune to voltage noise.  The typical ground plane noise is caused
        by high currents in the plane that cause minute votage shifts across
        the board.  The simplist solution being to cut out and isolate a
        section of the plane.

        However voltage noise on the power lines can be a problem.  To isolate
        this noise you can use a series resistor and a local bypass cap to
        filter the noise.  This technique can also work in the opposite
        direction essentialy keeping noisy circuits isolated from injecting
        noise back to the global supplies.

                                                     +--------+
        Global +Vcc      10-100 ohm       Local +Vcc |        |
        -----------------/\\/\\---------*--------------|        |
                                      |              |        |
                                     === Cb          |        |
        Gnd (plane)                   |              | Analog |
        ------------------------------**-------------| Circuit|
                                       |             |        |
                                      ===            |        |
        Global -Vcc      10-100 ohm    |  Local -Vcc |        |
        -----------------/\\/\\----------*-------------|        |
                                                     +--------+

       SWITCHING NOISE
       ---------------
       In many high speed logic designs it is often neccesary to drive
       large currents for short periods of time to achieve fast slew
       times.  In the circuit shown, the high current required 'Inoise'
       is essentially supplied by a local bypass capacitor which acts
       as an energy storage device.  During the non-switching time the
       capacitor is trickle charged to replenish the charge lost to the
       transistion.  The reason this works so well is that the Inoise
       current loop completes its loop localy since the current sees
       a high resistive path through the isolation resistor.  Other
       devices such as inductors can also be used for high frequency
       isolation, but for op-amps and other low power devices a resistor
       will be sufficient.

                                                     +--------+
        Global +Vcc      10-100 ohm       Local +Vcc |        |    Inoise
        -----------------/\\/\\---------*--------------|        | ---+
                                      |              |        |----+ |
                                      |     +----->  | Noisy  |    | V
                                     === Cb | Inoise | Circuit|   === Cload
                                      |              |        |    |
        Gnd (plane)                   |              |        |   ///
        ------------------------------*--------------|      it|
                                                     |        |
                                                     +--------+

    MULTITASKING APPLICATIONS
    -------------------------
      It is possible for multiple DOS type applications to co-exist in
      the DSK when multiple DOS shells are invoked.  However there are
      certain rules that must be followed.

      1) Multiple DOS applications are allowed by using TimeSlice
         management routines.
      2) Graphics based DOS applications must be run full screen
      3) DOS application boxes should be set to run in the background
      4) Port ownership is not arbitrated through software interlocks
      5) Port ownership is protected in an application by preventing
         the OS task swap while a DSK command is in progress.

    BLINKING LED (PWM DRIVER)
    -------------------------
     When the DSK power is first connected the state of the PWM output is not
     configured and the LED can glow either RED or GREEN.  A startup stub in
     the DSK kernel then initializes the two on-chip timers to approximately
     300.0 and 300.5 Hz.  These two timers are then applied to an XOR gate
     which acts as a differential phase detector whose output is a triangle
     wave.  The phase accumulates at the rate F1-F2 radians per second
     or 0.5 Hz.

     NOTE:
      A three-phase PWM signal can be built using an external counter/divider
      with three separate phase angles at one frequency.  By then using a
      a DSP timer for the other frequency the 3-phase field rotation rate can
      can be precisely controlled.  The 3 phase triangle waves are relatively
      close to sinusoidal but the amplitude cannot be adjusted.

      The PWM generator can also be used for a simple DAC output.  By choosing
      F1=F2 the PWM output is a DC signal whose level is proportional to the
      phase difference of F1 and F2.  However, since TIM0 and TIM1 are both
      used, you cannot also use the AIC since TIM0 is used for the AIC master
      clock.  In this case a clock can be added to the AIC jumper block.

    CONTINUED IN VOLUME 2

KEL 02/05/97