-----------------------
                        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