SwiftNet Host Software
SwiftNet Host Software
5 H os t So f t w ar e - U s e r ’ s G u i d e Page 1
USER’S GUIDE
SwiftNet 3.5
Host Software
Solaris / HP 9000/700 / Digital UNIX Version
Pentek, Inc.
One Park Way
Upper Saddle River, NJ 07458
(201) 818-5900
http://www.pentek.com/
Pentek grants to you a non-exclusive, non-transferable license to use the object code and source code Programs and
related documentation in this package by a single user computer. A single user computer is defined as any stand-alone
machine, or any individual machine connected to a network, on which only a single user is able to use the Programs. Use
of the Programs by more than one user requires additional paid licenses (contact factory for details).
You may make two copies of the Programs for backup, modification, and archival purposes. Title of the Programs is not transferred
to you by this license. Any sublicense, assignment, or other transfer of Programs or the rights or obligations of this agreement with-
out the written prior consent of Pentek is prohibited.
Software Limitations
Pentek does not warrant that the programs will be free from error or meet your specific requirements. You assume complete
responsibility for decisions made or actions taken based on information obtained using the programs. Any statements made
concerning the utility of the programs are not to be construed as expressed or implied warranties. Pentek makes no war-
ranty, either expressed or implied, including but not limited to, any implied warranties of merchantability and fitness for a
particular purpose, regarding the programs an makes the programs available solely on an “as is” basis. Pentek shall not be
responsible of incidental or consequential damages.
Printed in the United States of America. All rights reserved. Contents of this publication may not be reproduced in any form without written permission.
Sw i f t Ne t 3 . 5 H os t So f t w ar e - U s e r ’ s G u i d e Page 3
Table of Contents
Page
Chapter 1: Overview
Chapter 2: Installation
Rev. H
P ag e 4 S w i f t N e t 3 . 5 Ho s t So f t w ar e - U s e r ’s G ui d e
Table of Contents
Page
Rev. H
Sw i f t Ne t 3 . 5 H os t So f t w ar e - U s e r ’ s G u i d e Page 5
Table of Contents
Page
Rev. H
P ag e 6 S w i f t N e t 3 . 5 Ho s t So f t w ar e - U s e r ’s G ui d e
Table of Contents
Page
Rev. H
Sw i ft Net 3 .5 Ho st So f tw a re - Us er’s G u id e Pa g e 7
Chapter 1: Overview
Support for a wide range interconnect schemes, including shared memory on VME
and MIX buses, bus adapters, embedded hosts, TMS320C40 communication ports,
and Ethernet links
The SwiftNet File I/O Server snio and sniox, which includes two libraries that
simplify the use of host resources by providing a familiar standard C interface to file
and console I/O
All of Pentek's more sophisticated software offerings, including the SwiftTools DSP
Software Development Package and File Transfer Language (FTL), rely upon the
SwiftNet protocol to facilitate communication between the host system and DSP targets.
Model 4941 is a VxWorks developers package for 680x0, SPARC, and PowerPC-based Node
Processors (see the SwiftNet Server Libraries for VxWorks User’s Guide) that utilizes an Ethernet
link for Host-Node Controller communications. SwiftNet utility programs, the SwiftNet API,
and SwiftNet I/O libraries are supplied on CD-ROM and described in this manual.
Rev. H
Pa ge 8 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
Table 1-1, below, lists all Pentek products are supported by SwiftNet, and any application
notes.
Rev. H
Sw i ft Net 3 .5 Ho st So f tw a re - Us er’s G u id e Pa g e 9
Kernel The SwiftNet Kernel is the lowest level of inter-device communication for
DSP targets. The function of the kernel is to receive a signal through an
interrupt from another processor. The kernel will then either call a local
Interrupt Service Routine associated with that signal, or pass the signal on
to another processor.
NOTE: A SwiftNet Host may also be a Node if the SwiftNet devices are
directly accessible (i.e., a Sun system with an embedded VMEbus
card cage).
Server The SwiftNet Server is a process run on the Node processor that
downloads the SwiftNet kernel to the Target DSP(s) and otherwise
manages the SwiftNet protocol.
Rev. H
Pa ge 10 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
If you need assistance with installing or using SwiftNet software, Pentek’s customer
service may be contacted in the following ways:
Email: [email protected]
Please have the following information ready before calling, or include it in your email:
Model of host
SwiftNet version
monospace bold In examples, indicates that the user should type the text
verbatim.
[xxx,yyy] In examples, indicates that the user should enter one and only
one of the parameters enclosed in brackets. The brackets
themselves should not be entered.
Rev. H
Sw i ft Net 3 .5 Ho st So f tw a re - Us er’s G u id e P ag e 1 1
Chapter 2: Installation
This chapter describes how to install Pentek’s SwiftNet Host Software and drivers for
supported bus adapters and embedded processor boards. SwiftNet Host Software is
provided on CD-ROM. Contact Pentek if another media format is required.
NOTE: You must have root access to the system on which SwiftNet is being installed.
Section 2.6 covers bus adapter and embedded host device driver installation
This section provides step-by-step instructions for installing software packages from
the Pentek software distribution CD-ROM. If you require another media format, contact
Pentek at the phone number provided on the title page of this manual.
login: root
Password: ********
Rev. H
Pa ge 12 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
2) Using your user account, run the Pentek Software CD Extraction Utility with the
commands appropriate to your platform (the CD-ROM device name may vary):
login: username
Password: ********
# ./extract.sol
# ./extract.hp
or: # cd /cdrom/SOFTWARE
# "./EXTRACT.HP;1"
# ./extract.dec
3) The Pentek Software CD Extraction Utility will list all Pentek software packages
available on the distribution CD. Select SwiftNet Host Software option.
4) When prompted for the Destination directory, enter the name of the directory into
which the software should be installed.
NOTE: The Destination directory must exist prior to running the Extraction Utility. The
software selected in Step 3 will be installed into a subdirectory below the
specified Destination directory.
Rev. H
Sw i ft Net 3 .5 Ho st So f tw a re - Us er’s G u id e P ag e 1 3
% mkdir /usr/local/swiftconfig
2) The following environment variables are required for proper SwiftNet operation and
should be added to the .login or .cshrc file located in your $HOME directory. These
variables must be set prior to launching OpenWindows or HP Vue.
Set the MANPATH environment variable to point to each man page directory:
If you are using SwiftTools (2.5 or later only) and the TI compiler with SwiftNet, set
the DSPTOOLS environment variable to point to the directory where the TI compiler
is installed:
If you wish to access the SwiftNet demo projects from within SwiftTools, set the
SWIFTTOOLS_PROJ environment variable as shown below:
3) Add the directory $SWIFTNET_HOME/xxx/bin to your path (where xxx is solaris for
Solaris 2.x, hp9700 for HP-UX 9.0x/10.10, or alpha-unix for Digital UNIX), either by
modifying your existing path or by adding the following line after it:
NOTE: This directory should be placed BEFORE any SwiftTool path entries.
Rev. H
Pa ge 14 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
Network operation is typical and supports multiple connections to one or more DSP
targets.
The operating mode is determined by which shared library is used, and can be easily
changed. The following environment variable should be placed after any existing
shared library environment variable. Replace libx with libl for local mode or libn
for network mode.
Refer to Section 3.1 of this manual for a full description of these arguments.
5) HP-UX 9.0x/10.10 users only: In order for interactive utilities such as PNCFG and
SwiftTools to display properly, add the following two lines to the /.vue/sessions/
current/vue.resources file while logged in as root:
pncfg*font 9x15
swift*font 9x15
Rev. H
Sw i ft Net 3 .5 Ho st So f tw a re - Us er’s G u id e P ag e 1 5
SwiftNet supports the Digital Equipment Alpha series processor. However, at this time
SwiftNet requires using Digital UNIX OS. Microsoft Windows NT is not supported when
using a DEC Alpha processor.
A kernel device driver for the VME bus is included in the DEC UNIX Swiftnet
package. This device module must be installed in the kernel before using the
SwiftNet driver.To install SwiftNet, do the following steps:
The SwiftNet installation script installs the SwiftNet modules and displays the
following on the screen:
Once the system has rebooted, the driver can be loaded and unloaded with
the following commands:
This section contains some important notes on using DEC UNIX with SwiftNet.
Memory scanning outside of short address space is not supported. Before using the
pncfg tool, you need to know the A24 and A32 memory map addresses. It is required
that the memory space reserved by the inbound PCI mapping of the DEC Alpha
VME board be excluded in the memory map (see the Hardware Reference for the
AXPvme board--the DEC Alpha VME board). Due to limitations in the current release
of the DEC UNIX operating system, access to VME address space where no VME
device exists causes a panic in the DEC UNIX kernel.
Rev. H
Pa ge 16 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
DSP boards on the MIX bus are not currently supported in SwiftNet for DEC UNIX
on the DEC Alpha processor.
SwiftNet supports the following bus adapter and embedded processor boards:
The sections that follow, contain installation instructions for each bus adapter and
embedded processor board.
Rev. H
Sw i ft Net 3 .5 Ho st So f tw a re - Us er’s G u id e P ag e 1 7
The Universal VME Interrupt driver allows you to process VMEbus interrupts from
Themis and Force cards using the Solaris OS. Table 2-2 below provides compatibility
information for the various boards and drivers. The subsection below provides the
proper installation procedure for the driver. This driver is not compatible with the
SwiftNet packages for DEC Alpha and HP-UX 9.0x/10.x.
The steps below provide directions for installing Pentek’s leaf driver for
compatible Themis and Force products.
NOTE: If you need to get the Themis patch, contact Themis Computer. They
can also provide you with additional information on the patch. The
updated themvme driver should reside in either: /kernel/drv or
/platform/sun4u/kernel/drv depending on where the original
driver was installed.
Rev. H
Pa ge 18 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
If frcint has already been added to the system, it must be removed before
adding it again.
5) Verify and update, if needed, the frcint.conf file. This file is updated to use
interrupt level 3 and vectors 0xd0-df by default. If you want to use other
levels and vectors, you should ensure these are set properly.
The universal VME interrupt driver uses the following pndisp option;
In order to access the VMEbus using the Themis driver, make sure read
permission is assigned to usr/group/others for /dev/vme16d16,
/dev/vme24d16. To assign read permissions, do the following;
b) cd to /dev
Rev. H
Sw i ft Net 3 .5 Ho st So f tw a re - Us er’s G u id e P ag e 1 9
The steps below provide directions for installing Pentek’s leaf driver for a
Bit 3 Model 616/617 PCI-to-VMEbus Adapter on a PCI based Sun using Bit 3’s
946 driver.
If btpint has already been added to the system, it must be removed before
adding it again.
Rev. H
Pa ge 20 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
5) Verify and update, if needed, the btpint.conf file. This file is updated to
use interrupt level 3 and vectors 0xd0-df by default. If you want to use
other levels and vectors, you should ensure these are set properly.
The universal VME interrupt driver uses the following pndisp option;
Rev. H
Sw i ft Net 3 .5 Ho st So f tw a re - Us er’s G u id e P ag e 2 1
SBus adaptor card(s) must be installed in your Sun system prior to installing the Bit 3
device driver. However, the driver will load properly with the remote system (i.e., the
VME cage) powered off or with the cable disconnected.
The files required by the Bit 3 adaptor are located in the directory $SWIFTNET_HOME/bit3/
944/v3.4 (Solaris 2.x). These directories contain the following subdirectories:
sys Contains source files, makefile, and installation script for the Bit 3 SBus
device driver.
src Contains source files and makefile for all Bit 3 example programs. The
makefile can be used to compile all example programs for a particular
SBus adaptor model.
# cd $SWIFTNET_HOME/bit3/944/v3.4/sys
# make install
The installation script creates links in /usr/include/sys and copies the installation
scripts and compiled object file to the /dev directory.
4) When the installation script prompts for the number of devices to create, enter the
number of Bit 3 SBus adapters installed. A unique entry for each adaptor will be
added to the /dev directory, starting with /dev/bts0. Devices are numbered by the
sequence of their installation rather than by their SBus slot numbers. Thus, the first
Adaptor installed will be /dev/bts0, the next will be /dev/bts1, etc.
5) Verify that the hardware and device driver are properly installed by entering the
command below:
# /usr/sbin/modinfo
Rev. H
Pa ge 22 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
If this statement does not appear, the SBus Adaptor card is not properly installed. If
that statement is accompanied by the comment (no driver), the card is properly
installed but the device driver is not.
NOTE: Both the Model 943 and Model 944 device drivers support host interrupts from
the DSP board.
The PTI driver handles are named ptvmexxdyy where xx and yy are the VMEbus
access type. The A24/D16 driver handle would be ptvme24d16. These handles must be
symbolically linked to names in the format of vmexxdyy. This can be done by issuing
the following commands, assuming the PTI driver handles were installed in the /dev
directory:
# cd /dev
# ln -s ptvme24d16 vme24d16
2.11 Force 2CE, 3CE, 5CE, 5V, or CPU-10 VMEbus Embedded Processor Solaris
2.x Device Driver Installation
Each manufacturer provides VMEbus device drivers specific to their hardware. Refer to
the manufacturer’s documentation for installation instructions. To determine if your
Force driver and product is compatible with Pentek’s Universal VME Interrupt Driver,
see Table 2-2, on Page 17. 2CE, 3CE, and 5V board users should observe the following
instructions.
NOTE: Force 2CE and 3CE users should use version 1.9 of the Force driver, which is not
compatible with Pentek’s Universal VME Interrupt Driver. 5CE users who wish
to use the 1.9 Force driver should follow the steps below. If you want to use the
Universal VME Interrupt Driver, follow the installation instructions starting on
Page 17.
Rev. H
Sw i ft Net 3 .5 Ho st So f tw a re - Us er’s G u id e P ag e 2 3
2.11 Force 2CE, 3CE, 5CE, 5V, or CPU-10 VMEbus Embedded Processor Solaris
2.x Device Driver Installation (continued)
# cp $SWIFTNET_HOME/solaris/bin/vmeint_2ce /usr/kernel/drv
# cp $SWIFTNET_HOME/solaris/bin/vmeint_2ce.conf /usr/kernel/drv
3) Enter the following command to confirm that the driver has been created:
# ls /devices/vme@1,efe00000/vmeint:vmeint
If the system reports that the file is not found, driver installation has failed.
# ln -s /devices/vme@1,efe00000/vmeint:vmeint /dev/vmeint
5V boards only:
# cp $SWIFTNET_HOME/solaris/bin/vmeint_5v /usr/kernel/drv
# cp $SWIFTNET_HOME/solaris/bin/vmeint_5v.conf /usr/kernel/drv
3) Enter the following command to confirm that the driver has been created:
# ls /devices/iommu@0,10000000/VME@0,7ffffe00/vmeint:vmeint
If the system reports that the file is not found, driver installation has failed.
# ln -s /devices/iommu@0,10000000/VME@0,7ffffe00/
vmeint:vmeint/dev/vmeint
Rev. H
Pa ge 24 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
2.11 Force 2CE, 3CE, 5CE, 5V, or CPU-10 VMEbus Embedded Processor Solaris
2.x Device Driver Installation (continued)
NOTE: The 2CE/3CE/5V device driver supports host interrupts from the DSP board
under Solaris 2.4 and 2.5.
2.12 HP 743i, 747i, and 748 VMEbus Embedded Processor HP-UX 10.10 Device
Driver Installation
SwiftNet includes kernel drivers for HP-UX 10.10, however before installing these Pentek
drivers, the following HP-UX patches must first be installed:
PHKL_7223
PHCO_7074
PHSS_7224
These patches are available from the January 1997 Extensions CD, or from the Hewlett-
Packard web site at: http://us-support.external.hp.com/
# cd swiftnet-3.4/hp9700-10/lib/ptk
# cp libptk.a /usr/conf/lib
# cp ptk /usr/conf/master.d
2) Open the ptk file and edit, for each device, by replacing the xx in ptkxx with the
numbers shown in Table 2-3 below for the pentek device you are using. Then
remove the asterisk (comment symbol) on those lines.
Rev. H
Sw i ft Net 3 .5 Ho st So f tw a re - Us er’s G u id e P ag e 2 5
2.12 HP 743i, 747i, and 748 VMEbus Embedded Processor HP-UX 10.10 Device
Driver Installation (continued)
# cd /stand/build
# /usr/lbin/sysadm/system_prep -s system
4) Edit /stand/build/system to add the appropriate driver. For example, for the
Model 4285, add ptk85. The system file will look similar to the listing below:
# /usr/sbin/config -s system
# make -f config.mk
# mv /stand/system /stand/system.prev
# mv /stand/vmunix /stand/vmunix.prev
# mv /stand/build/system /stand/system
# mv /stand/build/vmunix_test /stand/vmunix
Rev. H
Pa ge 26 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
2.12 HP 743i, 747i, and 748 VMEbus Embedded Processor HP-UX 10.10 Device
Driver Installation (continued)
//
// Configure a 4284: A16 base address = 0x0000
// A24 base address = 0x000000
// A32 base address = 0x00000000
// A16 size = 0x100
// A24 size = 4MB
// A32 size = 16MB
// Processor Declaration
// Name CPU/Card ID Options
// Number
proc Model_4284 * *
memory A24 {
// address name card
0x000000:4M dual24_port84 Model_4284
}
memory A32 {
// address name card
0x00000000:16M dual32_port84 Model_4284
}
These example files define a Model 4284. Similar files can be created for models 4280,
4283, and 4270 by changing the names. The base addresses and memory sizes for
each memory type (A16, A24 and A32) must match the hardware configuration on
the Pentek board. Refer to the operating manual of the board you will be accessing
for a complete description.
For a detailed information on the vme.CFG file, refer to the VME Configuration Guide
for HP-UX.
# vme_config
Rev. H
Sw i ft Net 3 .5 Ho st So f tw a re - Us er’s G u id e P ag e 2 7
2.12 HP 743i, 747i, and 748 VMEbus Embedded Processor HP-UX 10.10 Device
Driver Installation (continued)
9) If any errors occur, refer to Appendix B: Warning and Error Messages listing in the
VME Configuration Guide for HP-UX.
10) Once you have a correct configuration (indicated by a message from vme_config that
a configuration was successfully generated), you must ensure that your VME card
configuration matches that specified in the vme.CFG file. The file
/etc/vme/system.log contains a description of your current configuration.
Dual Port RAM Base Addresses for each board must be set so as not conflict with
any other device in the VME card cage. (Note that on Pentek Models 4254, 4257,
4244, and 4247, the Base Address of Global SRAM is hard-wired and cannot be set
in hardware or software.)
The VME Interrupt Level must be set to match the setting in the PNCFG Target
Configuration Utility using the on-card jumpers. (See the Operating Manual of
your specific board for more details.)
Models 4269 and 4270 must also be configured such that both or all four
processors can issue VME Interrupts on the same level (this is the factory default
setting, at Level 3). See Section 2.2.6 of the 4269 or 4270 Operating Manual for
further details.
2) Use the pncfg utility to configure SwiftNet (see Section 3.2 of this manual for
detailed information on PNCFG).
3) Use the sntest utility to verify that your hardware and software are communicating
properly:
Rev. H
Pa ge 28 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
Rev. H
Sw i ft Net 3 .5 Ho st So f tw a re - Us er’s G u id e P ag e 2 9
2) A Sun workstation with an integrated VMEbus where Pentek hardware shares the
system bus with the Sun processor board
3) A VMEbus cage with an embedded SPARC processor board (Force 2CE, 3CE, 5CE,
CPU-10, and General Micro Systems V64)
5) A VMEbus processor board (680x0 node controller) which communicates with a host
through an Ethernet connection
In the first three configurations, the SwiftNet Server PNDISP must be started on the host
with a specific driver for the hardware being used. In the fourth configuration, when
using an HP embedded processor board or an HP workstation with an integrated
VMEbus, PNDISP is required. In the case of an Ethernet connected node controller, the
SwiftNet Server is started under VxWorks or is supplied as firmware in the form of an
EPROM (see the SwiftNet Server Libraries for VxWorks or the SwiftNet Node Firmware
manual depending upon your hardware configuration).
NOTE: PNDISP should not be run when the local SwiftNet libraries are used.
where:
The following sections describe the specific arguments for each hardware and operating
system configuration.
Rev. H
Pa ge 30 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
3.1.1 Starting the SwiftNet Server on a Sun with a Bit3 Model 616/617
PCI-to-VMEbus Adaptor(Pentek Models 4228/4229)
In this configuration host interrupts from the DSP boards are supported.
3.1.2 Starting the SwiftNet Server on a Sun with a Bit3 Model 466 Sbus-to-
VMEbus Adaptor (Pentek Model 4221)
In this configuration host interrupts from the DSP boards are supported.
In this configuration host interrupts from the DSP boards are not supported.
Rev. H
Sw i ft Net 3 .5 Ho st So f tw a re - Us er’s G u id e P ag e 3 1
When running under Solaris 2.x, host interrupts from the DSP boards are not
supported.
3.1.6 Starting the SwiftNet Server on a Sun with the Universal VME
Interrupt Driver
The SwiftNet Server is started on a Sun with an with the Universal VME
Interrupt Driver as follows:
In this configuration host interrupts from the DSP boards are supported.
Rev. H
Pa ge 32 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
3.1.7 Starting the SwiftNet Server on a Force 2CE, 3CE, 5CE or CPU-10, or
General Micro Systems V64 (Solaris 2.x)
Host interrupts from the DSP boards are supported on the 2CE and 3CE.
They are not supported on the CPU-10 and V64.
Host interrupts from the DSP board are supported on models 4280, 4283,
4284, 4270.
At the time of this release, host interrupts from the DSP board are only
supported on the models 4200 and 4201.
Rev. H
Sw i ft Net 3 .5 Ho st So f tw a re - Us er’s G u id e P ag e 3 3
Before a Target device may be opened in SwiftTools, the Node Server requires certain
information about the configuration of the target devices. The program PNCFG
facilitates this process in a menu-driven environment. This program must be run before
attempting to communicate with the hardware devices in your card cage. The program
has two modes, interactive and command-line.
PNCFG can be run in two modes: interactive and command line. To start
PNCFG in the interactive mode type:
# pncfg
After node configuration files have been saved using PNCFG in the
interactive mode, subsequent launches of PNCFG can be done from the
command line. The syntax is as follows.
This command will retrieve the node configuration file stored by a Configure-
Save command in interactive mode. At least one node name must be
specified. The command line options are described below.
Rev. H
Pa ge 34 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
PNCFG
Window Node Server Configure Memory Map Memory Scan
Node 1 not connected Node 1 -Virtual "node" baseboard
Rev. H
Sw i ft Net 3 .5 Ho st So f tw a re - Us er’s G u id e P ag e 3 5
Each Node listed above represents a single VME card cage. A single node may
contain one or more baseboard(s) or MIX Stack(s). The pull-down menus and
their selections are described on the following pages. Be aware that the screen
shown on the previous page is not what you should expect to see when the
program starts. Initially, only the Window and Node menus are available.
The methods used to make selections from the pull-down menus in PNCFG
are summarized below.
Menu Selections Point to the desired PNCFG menu bar selection and
click the left mouse button. Then point to the desired
menu item and click the left mouse button. When
selecting items from the Node (left) window, the
mouse cursor must point at the Node Name field.
Rev. H
Pa ge 36 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
NOTE: When creating Node names, they are based on the computer’s
TCP/IP name. When using a VXWorks node, SwiftNet Node
names are based on the VXWorks card name.
After Nodes have been created, use the Server Menu to enable
communications between SwiftTools and one and more of the defined Nodes.
Only nodes that are connected in PNCFG can be used as Target devices in
SwiftTools. This menu is unavailable if no Nodes have been created.
Rev. H
Sw i ft Net 3 .5 Ho st So f tw a re - Us er’s G u id e P ag e 3 7
The Configure Menu is used to create the list of hardware devices that
comprise the Targets residing in the connected Nodes. Pop-up windows are
used to allow the user to assign a name to each Target device within a given
node, and to define the VME addressing mode and the base (offset) address
of the Dual-Port or Global RAM on a MIX Baseboard or VME Processor board.
Another menu choice allows the user to save the node configuration to a file.
Target-Add
OK CANCEL
Rev. H
Pa ge 38 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
Board Name Enter the name you wish to use in SwiftTools when
referring to this Target board. This field has no
default. If no board name is entered, the Target-
Add operation fails.
Slot Number Enter the number of the VME slot that houses the
Target. The default is 0. This entry is for user
information only and is not used by the program in
any way, since VME systems access connected
boards by memory addresses, not by slot numbers.
Configure-Add (continued)
Dual Port This field indicates the amount of Global Dual Port
RAM Size RAM present on the Target processor board. For the
model 4283, this may be 1 MB, 4 MB or 8 MB. The
allowable values may be cycled through by hitting
the space bar or by placing the mouse cursor within
the field and clicking the left button.
A16 Base The base (offset) address used for VME transactions
Address in A16 space. The default value is 0x0000. The
content of this field should match the on-card
setting, generally accomplished using jumpers. See
the Target board's Operating Manual for details.
DPR Access This field allows you to select the mode in which
Mode the VMEbus interacts with the Target Baseboard’s
Dual-Ported Global RAM. The default mode is A32/
D32. Other options are A24/D32, A32/D16, and A24/
D16. You can cycle through these four options by
hitting the space bar with the field highlighted, or
by placing the mouse cursor within the field and
clicking the left button.
Rev. H
Sw i ft Net 3 .5 Ho st So f tw a re - Us er’s G u id e P ag e 3 9
DPR Base This field allows the user to define the base (offset)
Address address of the Target’s Global Dual-Port RAM for
VME Transactions in A24 and/or A32 space. The
default address is 0x00000000. The content of this
field should match the on-card setting, which may
be accomplished using jumpers, switches or by
programming a register in A16 space. See the Target
board's Operating Manual for details.
Configure-Add (continued)
Rev. H
Pa ge 40 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
Board Name Enter the name you wish SwiftTools to use when
referring to this Target board. Board names may be
a maximum of eight characters long. This field has
no default. If no board name is entered, the Target-
Add operation fails.
Slot Number Enter the MIX bus “slot” number (i.e. board
position in the stack) for this board. The default is 0,
and the only other acceptable entries into this field
are 1 or 2. The list of acceptable entries may be
cycled through by pressing the space bar or by
clicking the left mouse button in the field.
Rev. H
Sw i ft Net 3 .5 Ho st So f tw a re - Us er’s G u id e P ag e 4 1
Configure- Removes the selected board from the Target list. When this
Remove option is selected, a window appears showing all Target boards
in the selected node. Select the board to be removed by clicking
on its line with the left mouse button, or by highlighting its line
with the and arrow keys and then pressing <return>. A
baseboard may not be removed until all MIX modules associated
with it have been removed first.
Configure- This menu option reads and lists the Target configuration files
Update from the Node.
PNCFG creates a memory map for each VMEbus address space as they are
scanned using the Memory-Scan option or as boards are added to a target's
configuration. This option is only enabled after a node has been connected.
Rev. H
Pa ge 42 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
PNCFG scans each VMEbus address space for boards occupying address
ranges. This is useful for determining occupied address before attempting to
add a board using Configure-Add or for confirming user set base addresses
on each board. After an address space is scanned the results are saved and
can be re-displayed with the Memory-Map option.
NOTE: The Memory Scan feature scans ALL locations in the address space.
This may cause unpredictable behavior when some locations are
accessed on non-Pentek boards.
Rev. H
Sw i ft Net 3 .5 Ho st So f tw a re - Us er’s G u id e P ag e 4 3
Rev. H
Pa ge 44 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
-v Verbose mode.
-b Don't clear the .bss section (usually used for uninitialized data).
-p Load the object file found in the directory specified by the Project name, i.e.:
This command uses the name of the project instead of the COFF file. It
loads and executes the file demo.xxx, which is found in the project
directory named demo, and where xxx is automatically set to the type of
target specified by board_1. If board_1 is a 4270 the file demo.x70 is loaded,
if the board is a 4284, the file demo.x84 is loaded.
SNTEST displays a count of each successful transmission, and runs until interrupted by
the user with ^C.
Rev. H
Sw i ft Net 3 .5 Ho st So f tw a re - Us er’s G u id e P ag e 4 5
SNINFO displays information about a specific Target board. The command syntax is as
follows:
where:
<node-name> and <board-name> are the names assigned to the desired Target
using PNCFG.
NOTE: When using the -f option, the network must support reverse DNS
lookup in order for the names of the nodes to appear, otherwise
only the IP numbers are displayed.
Rev. H
Pa ge 46 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
Rev. H
Sw i ft Net 3 .5 Ho st So f tw a re - Us er’s G u id e P ag e 4 7
When using the Swiftnet API, only one Swiftnet Signal can be sent to a SwiftNet device
simultaneously. So for example, if a signal is being sent to an open SwiftNet device, using
PNKC_SEND or PNKC_SENDEX, it is necessary to wait for it to complete before calling
PNKC_SEND, PNKC_SENDEX, PLOG, or PLOGF.
When compiling code that uses this API on the host, one of the following defines must
be set: PENTEK_SOLARIS, PENTEK_OSF1, or PENTEK_HPUX. In addition, the library
libsocket must be linked in. Previous code based on the SwiftNet API needs to be re-
compiled using the SwiftNet 3.4 header files and libraries. It is also recommended that
you change previous occurrences in your code of u_long types to u_int_32.
A new function, added in SwiftNet 3.4, pnkc_sendEx() enables the use a data buffer
larger than 1024 longwords.
Rev. H
Pa ge 48 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
DSP API
$SWIFTNET_HOME/[c30,c40]/include/*.h
$SWIFTNET_HOME/[c30,c40]/lib/[swftnt.lib,swftntr.lib] (see note)
$SWIFTNET_HOME/[4283,4270, etc]/include/*.h
$SWIFTNET_HOME/[4283,4270, etc]/lib/[*.lib,*.cmd]
To allocate shared memory use shmalloc(). Memory boundaries are defined in the
linker file with _shmem1_base & _shmem1_top.
Rev. H
Sw i ft Net 3 .5 Ho st So f tw a re - Us er’s G u id e P ag e 4 9
shmint(mode)
Zeros out the shared memory area. This routine needs to be used prior to
allocating shared memory.
In most cases shared memory is zeroed from a cold boot. However, it may be
necessary to use mode 1 when debugging, or in other special conditions.
shmFree(ptr)
_shmem1_base= _shmem2_base=
_shmem3_base= _shmem4_base=
DSP memory base address of sections 1, 2, 3, and 4. You can define up to four
sections of memory. shMalloc stops when any shmemX_base amount is set
to equal zero (i.e. _shmem2_base=0).
_shmem1_top= _shmem2_top=
_shmem3_top= _shmem4_top=
DSP memory ending address range for each section. Unused sections should
be set to 0 (zero).
Rev. H
Pa ge 50 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
4.3 PNKC_INIT
STATUS pnkc_init()
The pnkc_init() function initializes the SwiftNet client API. It must be called before any
other function in the SwiftNet client API.
Parameters None
4.4 PNKC_OPEN
Parameters pcHndl
Pointer to a PNKCAPI_TYPE structure; used as a handle when calling
other SwiftNet client API functions
nodeName
Node name as defined by PNCFG
deviceName
Device name as defined by PNCFG
Rev. H
Sw i ft Net 3 .5 Ho st So f tw a re - Us er’s G u id e P ag e 5 1
4.5 PNKC_INFO
PNK_DEVHDR_PTR pnkc_info(pnkcHndl)
PNKCAPI_PTR pnkcHndl;
The pnkc_info() function returns a pointer to the device header structure of the device
specified by the handle, pnkcHndl.
Parameters pnkcHndl
Pointer to a PNKCAPI_TYPE structure; used as a handle when calling
other SwiftNet client API functions. The PNK_DEVICE_TYPE and
PNK_DEVHDR_TYPE structures are described below:
Return Values Returns a pointer to the device header structure on success, NULL on
failure
4.6 PNKC_SEND
The pnkc_send() function sends a SwiftNet signal to a previously opened SwiftNet device.
Parameters pnkcHndl
The argument pnkcHndl is the handle from a pnkc_open() call.
portNum
The signal is routed to the device port specified by portNum. For
DSP devices, each port represents a different processor on a board.
sig
The sig argument is a pointer to a SwiftNet signal structure
(described below).
ret
ret is a pointer to a SwiftNet return structure (described below).
Sig Structure The args substructure is used to specify a buffer of arguments. The
(continued) args.args_len member is the size of the buffer (in units of unsigned
longs), and the args.args_val member is a pointer to the argument
buffer. Similarly, the data substructure is used to specify a buffer of data.
If a buffer is not to be used, set the buffer length to zero and the buffer
pointer to NULL.
Since the system clocks responsible for calculating timeout delays vary,
timeout_ticks and tick_ulen may be translated. If tick_ulen is less
than the clock period, the clock period is used as the actual tick length.
Otherwise, the actual tick length is calculated as the largest multiple of
the clock period less than or equal to tick_ulen. Furthermore, the actual
number of ticks is adjusted such that the total timeout period is the
smallest multiple of the actual tick length that is equal to or greater than
the product of the original timeout_ticks and tick_ulen.
Rev. H
Pa ge 54 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
Sig Structure Although the return structure is used to return data from the device,
(continued) some of its members must be initialized before calling pnkc_send().
You have two options; either specify an allocated return buffer and
size, or let pnkc_send() allocate a buffer of the appropriate size. In the
latter case, you may use pnkc_free() to de-allocate the returned data
buffer.
The val member is used as a return value from the device, analogous
to a function call returning a value.
Return Values Returns OK on success, ERROR on failure. Failure to send a signal may
result from various conditions and there are currently no
distinguishing error codes. However, error messages describing the
failure are usually printed to stderr.
Comments Make sure that the data.data_len and data.data_val members of the
return structure are correctly set before each call to pnkc_send().
Rev. H
Sw i ft Net 3 .5 Ho st So f tw a re - Us er’s G u id e P ag e 5 5
4.7 PNKC_SENDEX
Target version: STATUS pnkc_sendEx(pnkcHndl, portNum, sig, ret)
Host version: STATUS pnkc_sendEx(pnkcHndl, portNum, sig, ret, dpr_args, dpr_data, dpr_ret)
PNKCAPI_PTR pnkcHndl;
u_int_32 portNum;
PNK_SIGNAL_PTR sig;
PNK_RETURN_PTR ret;
u_int_32 dpr_args; /* USED ONLY ON HOST */
u_int_32 dpr_data; /* USED ONLY ON HOST */
u_int_32 dpr_ret; /* USED ONLY ON HOST */
The function pnkc_sendEx() provides the same function as pnkc_send and all information
in the pnkc_send description applies to pnkc_sendEx. However, the transfer of data
through SwiftNet is no longer limited to 1024 longwords since data is located in shared
memory (dpr).
Parameters
pnkcHndl
The argument pnkcHndl is the handle from a pnkc_open() call.
portNum
The signal is routed to the device port specified by portNum. For
DSP devices, each port represents a different processor on a board.
sig
The sig argument is a pointer to a SwiftNet signal structure.
ret
ret is a pointer to a SwiftNet return structure.
dpr_args
dpr_args is the DSP address which points to the shared memory
buffer for arguments. You can only used this parameter on the
host.
Rev. H
Pa ge 56 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
dpr_data
dpr_data is the DSP address which points to the shared memory
buffer for data. You can only used this parameter on the host.
dpr_ret
dpr_ret is the DSP address which points to the shared memory
buffer for return data. You can only used this parameter on the
host.
Sig Structure The sig Structure is code is identical to pnkc_send. See pnkc_send
for sample code. As previously stated, when using the
pnck_sendEx() function you are not limited to 1024 Longword
buffer. However, you must allocate the buffer prior to using the
pnkc_sendEx() function using the shmalloc routine. shmalloc
and related routines are explained in Section 4.2.
4.8 PNKC_FREE
STATUS pnkc_free(ret)
PNK_RETURN_PTR ret;
The function pnkc_free() frees memory previously allocated for return data contained
in the structure pointed to by ret. It also sets the structure members data.data_len and
data.data_val to zero and NULL respectively. This function may only be used when the
memory was allocated by pnkc_send(). See pnkc_send for details.
Parameters ret
ret is a pointer to a SwiftNet return structure.
Rev. H
Sw i ft Net 3 .5 Ho st So f tw a re - Us er’s G u id e P ag e 5 7
4.9 PNKC_CLOSE
void pnkc_close(pnkcHndl)
PNKCAPI_PTR pnkcHndl;
Parameters pnkcHndl
Pointer to a PNKCAPI_TYPE structure; used as a handle when calling
other SwiftNet client API functions
4.10 PLOG
The function plog allows the DSP Target to output a message to the Server Console. The
plog function is provided with the Swiftnet API and doesn't require running SNIO.
Carriage returns are automatically inserted at the end of lines, so \n statements are not
required. It is also important not to call plog from a signal handler.
Parameters None
Rev. H
Pa ge 58 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
4.11 PLOGF
The function plogf is allows the DSP Target to output a formatted message to the Server
Console. The plogf function is provided with the Swiftnet API and is identical to the
stdio.h printf function except plogf doesn't require running SNIO. The plogf function
is similar to plog in that carriage returns are automatically inserted at the end of lines, so
\n statements are not required, and you should not call plogf from a signal handler.
Parameters format
Format is identical to stdio.h’s printf function format parameter .
Rev. H
Sw i ft Net 3 .5 Ho st So f tw a re - Us er’s G u id e P ag e 5 9
When compiling code that uses this API on the host, one of the following defines must
be set: PENTEK_SUNOS, PENTEK_SOLARIS, PENTEK_OSF1, or PENTEK_HPUX. In
addition, the library libsocket must be linked in.
This API is available for Solaris 2.x (SPARC), HP-UX 9.0x (HP 9000 Series 700), VxWorks 5.1
(680x0, SPARC), and Pentek DSP boards for developing applications that receive SwiftNet
signals. For SPARCstations and VxWorks processors, this API creates virtual devices that
can receive SwiftNet signals just like real DSP devices such as TMS320C30 and ‘C40 boards.
Signals are received asynchronously via hardware interrupts on real DSP devices and via
UNIX signals for virtual SwiftNet devices.
Rev. H
Pa ge 60 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
DSP API
$SWIFTNET_HOME/[c30,c40]/include/*.h
$SWIFTNET_HOME/[c30,c40]/lib/[swftnt.lib,swftntr.lib] (see note below)
$SWIFTNET_HOME/[4283,4270, etc]/include/*.h
$SWIFTNET_HOME/[4283,4270, etc]/lib/[*.lib,*.cmd]
Rev. H
Sw i ft Net 3 .5 Ho st So f tw a re - Us er’s G u id e P ag e 6 1
5.2 PNKD_INIT
DSP
STATUS pnkd_init()
The pnkd_init() function initializes the SwiftNet device API. It must be called before any
other function in the SwiftNet device API.
Comments pnkd_init() did not take an argument in SwiftNet versions 2.1 and
earlier. Therefore, if you are upgrading from SwiftNet 2.1 or earlier,
you must make this change and re-compile any VxWorks code that
uses this API.
Rev. H
Pa ge 62 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
5.3 PNKD_CREATEDEV
STATUS pnkd_createDev(dev)
PNK_DEVICE_PTR dev;
Parameters dev
dev is a pointer to a device structure PNK_DEVICE_TYPE that
contains the information about the virtual device to be created.
This same structure is used for both real and virtual devices.
The member parent is the name of the parent device if there is one.
For example, a MIX module’s parent is its base board. A null string, “”,
means that there is no parent device, i.e., it is a base board. Virtual
devices have no parents, therefore, this field must be set to “”.
5.4 PNKD_CONNECT
Parameters sigNum
The SwiftNet signal number, from the range 0-255, to which the
function newFunc is connected.
newFunc
newFunc is a SwiftNet signal handler function. It is called as an ISR
(Interrupt Service Routine) on real SwiftNet devices. Normal C
functions cannot be ISRs because they do not save and restore the
entire processor state. Section 4.6 of the 1991 edition of the TMS320
Floating-Point DSP Optimizing C Compiler user's guide describes
the naming convention used to create special C functions that can
be used as ISRs (The form is c_intXX, where XX is any two digit
number. This form notifies the compiler that the processor state
must be saved (with pushes) before executing the function, and
restored (with pops) before returning). For virtual SwiftNet
devices, newFunc is called from a UNIX signal handler and has no
naming restrictions.
oldFunc
Set to the previous connected handler if oldFunc is not equal to
NULL.
Comments For real devices, signals 0x80-0xFF are reserved for system use. Users
should only connect functions to signals 0x00-0x7F on real devices.
Rev. H
Pa ge 64 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
5.5 PNKD_ADDR
This function returns the SwiftNet node name, device (board) name, and processor
number via the passed pointers.
Parameters nodeName
Pointer to a string that will hold the node name.
devName
Pointer to a string that will hold the device name.
portNum
Pointer to a unsigned long that will hold the port (processor)
number.
5.6 PNKD_SIGNAL
PNK_SIGNAL_PTR pnkd_signal()
The function pnkd_signal() retrieves the incoming signal when called from the handler
function. When a signal is received, all signals are disabled and the appropriate handler
function is invoked. Signals remain disabled until the handler returns. The contents of
the signal argument and data buffers are valid until pnkd_return() is called.
Parameters None.
Return Values Returns a pointer to the incoming signal structure, NULL if no signal is
pending.
Rev. H
Sw i ft Net 3 .5 Ho st So f tw a re - Us er’s G u id e P ag e 6 5
5.7 PNKD_RETURN
STATUS pnkd_return(ret)
PNK_RETURN_PTR ret;
The pnkd_return() function acknowledges an incoming signal and returns data to the
client. The incoming signal data obtained with pnkd_signal() is no longer valid after this
call.
Parameters ret
A pointer to a PNK_RETURN_TYPE structure. This function must be
called from every SwiftNet signal handler before it returns.
5.8 PNKD_PAUSE
void pnkd_pause()
The function pnkd_pause() enables SwiftNet signals and waits until a signal has been
processed before returning. Signal are disabled when pnkd_pause() returns.
This function differs from pnkd_wait() on DSPs in that it will return immediately after
the SwiftNet signal's ISR returns. It does not wait for the node controller to finish
accessing shared memory.
Parameters None.
Comments For DSPs, pnkd_pause() returns after a SwiftNet signal's ISR has
returned. The node controller reads return data from shared memory
after pnkd_return() has been called by the ISR. It is possible that this
shared memory access is still going on when pnkd_pause() returns. If
the DSP application accesses shared memory immediately following
pnkd_pause() such that it locks out the node controller (this is
dependent on the DSP board being used), bus timeouts can occur.
Rev. H
Pa ge 66 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
5.9 PNKD_DISABLE
void pnkd_disable()
The function pnkd_disable() disables all incoming SwiftNet signals. Any pending signal
will not be received until signals are re-enabled with pnkd_enable(). Although the client
will not receive an error immediately as is the case when a particular signal is
unconnected, it may eventually timeout and cause an error.
Parameters None.
Comments Since disabling signals for too long may cause timeouts, it is strongly
recommended that signals only be disabled for very short periods of
time during critical regions of code.
5.10 PNKD_ENABLE
void pnkd_enable()
Parameters None.
Rev. H
Sw i ft Net 3 .5 Ho st So f tw a re - Us er’s G u id e P ag e 6 7
5.11 PNKD_WAIT
void pnkd_wait()
The function pnkd_wait() enables SwiftNet signals and waits until a signal has been
processed before returning. Signals are disabled when pnkd_wait() returns. This
function differs from pnkd_pause() in that it will not return until the shared memory
accesses by the node controller are complete. This avoids possible bus timeouts when
both the node controller and the DSP are trying to access shared memory at the same
time.
Parameters None.
Rev. H
Pa ge 68 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
Rev. H
Sw i ft Net 3 .5 Ho st So f tw a re - Us er’s G u id e P ag e 6 9
The SwiftNet File I/O Server allows the programmer to use familiar standard C I/O
functions, such as printf, scanf, fopen, etc., on Pentek DSP target processors. All I/O
requests are transferred to a host computer running the Swiftnet I/O server. The package
consists of a host server executable (snio or sniox), two libraries (snio.lib or
sniox.lib, and snstdio.lib), and two header files (snio.h and snstdio.h).
The snio library contains system level I/O functions, which are similar to those found
UNIX. The snstdio library contains buffered standard I/O functions.
sniox and sniox.lib use the extended SwiftNet API functions, otherwise they are
identical to snio and snio.lib.Throughout this chapter where snio is mentioned,
sniox can be substituted if SwiftNet’s extended API is used. It should also be noted that
sniox uses the same header file as snio (snio.h).
NOTE: There are eight (8) different libraries that can be used depending on the
memory model and SwiftNet API function desired. Both snio.lib and
sniox.lib can have four different memory models. No suffix - small
memory model, r - register passing parameter model (snior.lib), b - big
memory model (sniob.lib), and br - big memory model and register
passing parameter model (sniobr.lib).
Before using snio library functions, you must first call the appropriate initialization
function. If you plan to only use the low-level functions found in snio.lib, you must call
snio_init(). If you plan to use the buffered I/O functions found in snstdio.lib, you
must call snstdio_init(). You do not need to call snio_init() if you have called
snstdio_init().
Rev. H
Pa ge 70 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
The server must be properly shut down prior to the termination of your program. This
can be accomplished by calling snio_shutdown() when using only low-level functions, or
snstdio_shutdown() when using buffered I/O. The appropriate shutdown function may
be added to the atexit() list, as illustrated by the following example:
#include <stdlib.h>
#include <snstdio.h>
main()
{
if (snstdio_init(NULL) != OK)
{
plog("snstdio_init() failed\n");
return(-1);
}
atexit((void (*)())snstdio_shutdown);
printf("Hello world!\n");
}
The host portion of the standard I/O package consists of a single executable: snio. It can
be used to both load the target executable, and act as a server for processing I/O requests
from a DSP board.
node-name network node name of the system that contains the Pentek
DSP board
-p This option uses the name of the project instead of the COFF file.
It will load and execute the file projectname.xxx which is found
in the project directory named projectname and where xxx is
automatically set to the type of target specified by board_1. If
board_1 is a 4270 the file projectname.x70 will be loaded, the
board is a 4284 the file loaded will be projectname.x84, etc.
Rev. H
Sw i ft Net 3 .5 Ho st So f tw a re - Us er’s G u id e P ag e 7 1
The following is a listing of the snio library. The prototypes and macros for
this library are in snio.h.
int lseek(int fd, int Sets the seek pointer associated with the open file.
offset, int whence) whence must be either set to SEEK_SET, SEEK_CUR, or
SEEK_END. If whence is SEEK_SET, the seek pointer is
set to offset from the beginning of the file. If
whence is SEEK_CUR, the seek pointer is set to offset
from the current file position. If whence is
SEEK_END, the seek pointer is set to the file size plus
offset. On success, the current file location is
returned; on failure, -1 is returned.
Rev. H
Pa ge 72 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
int open(char *path, Open will open a path to a file, or device, and
int flags, int mode) return a path number to that device. The flags
argument must contain a single mode flag, and a
modifier flag, and can be obtained by ORing the
values together.
Modes:
Modifiers:
Rev. H
Sw i ft Net 3 .5 Ho st So f tw a re - Us er’s G u id e P ag e 7 3
int read(int fd, char Reads n bytes or longwords from the file
*buf, int n) corresponding to fd, into buf. On success, the
number of bytes or longwords read is returned. On
failure, -1 is returned.
Rev. H
Pa ge 74 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
NOTE: When calling any SwiftNet I/O function, ever source file must
contain the following declaration:
#include <snstdio.h>
sscanf() ungetc()
Rev. H
Sw i ft Net 3 .5 Ho st So f tw a re - Us er’s G u id e P ag e 7 5
The fopen() function contained in the snstdio library differs from the K&R
standard as follows:
fopen(name,mode)
Where:
Rev. H
Pa ge 76 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
There are two conditions where the error message [pnkd_init] semget:
No space left on device appears; if the semaphores provided by the
operating system needs to be increased, or if SNIO is terminated incorrectly
and the operating system doesn’t return semaphore and shared memory
resources.
For Solaris 2.5.x, the kernel does not have to be rebuilt since
SunOS 2.x kernel modules are automatically reloaded when
needed, making rebuilding the kernel unnecessary.
To change the values, enter a line in the /etc/system file using the
following syntax: set
semsys:seminfo_varible=value
Rev. H
Sw i ft Net 3 .5 Ho st So f tw a re - Us er’s G u id e P ag e 7 7
Example:
ipcs
Rev. H
Pa ge 78 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
Rev. H
Sw i ft Net 3 .5 Ho st So f tw a re - Us er’s G u id e P ag e 7 9
SwiftNet makes use of node controllers which manage communications between the
target DSPs and the host. Node controllers are typically MC680X0, SPARC, or PowerPC
based processor boards which reside in the card cage and connect to the host through an
Ethernet link. A host may also be a node controller as in the case of an embedded VME
card cage in the Sun, or a Sun with an SBus-to-VMEbus adapter.
The SwiftNet drivers contain target resident code which controls inter-device
communications. When a host process sends a SwiftNet signal to the DSP, the node
controller delivers it to the DSP by using shared memory and interrupts. The drivers uses
a pseudo interrupt vector table to supplement a standard interrupt vector table because
typically only one interrupt is available from the host to the DSP. User supplied ISRs as
well as built-in SwiftNet ISRs are loaded into this table. Figure 2 shows the
implementation of a typical application using the SwiftNet API.
SwiftNet
Built-In ISRs
SWIFTNET
DRIVERS
SwiftNet
Shared
Built-In
Memory
Pseudo number
ISRs
Pseudo Interrupt
Number
Input data Input data - pnkd_signal
User
Output data Output data - pnkd_return ISRs
Rev. H
Pa ge 80 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
PNCFG is used to configure the target board parameters and load the drivers, initialize
the interrupts vector table and initialize the pseudo interrupt vector table with built-in
SwiftNet ISRs. PNKD_connect can be used to load any user supplied ISRs into the pseudo
interrupt vector table. A SwiftNet signal is sent from the host using PNKC_send and is
received by the node controller. The node controller passes the signal to the DSP and an
ISR is dispatched. The DSP then looks in shared memory for the number of the pseudo
interrupt vector which is used to look up an ISR in the pseudo interrupt vector table. The
ISR can input and output data by using the API supplied functions PNKD_signal and
PNKD_return respectively.
The SwiftNet protocol is symmetrical in that it can use the same SwiftNet signals in both
host to target and target to host directions. Where the node controller and the SwiftNet
kernel accept SwiftNet signals on the target side, the process running on the host is a
virtual target which behaves like an actual DSP target. The DSP can send a signal to the
host by first interrupting the node controller. The node controller then passes a SwiftNet
signal to the virtual target, which uses a software signal that invokes a signal handler.
Figure 2 shows how this is implemented when running the reverb.c demo program.
Host Computer
I/O Server (virtual target)
bark.au /dev/audio
Network
Interface
implementation
dependent
Network
Interface
SwiftNet API
fread() fwrite()
reverb.c
Target DSP Board
Node Controller
implementation dependent
Rev. H
Sw i ft Net 3 .5 Ho st So f tw a re - Us er’s G u id e P ag e 8 1
The reverb.c program uses C standard I/O functions to read an audio file (bark.au) from
the Sun's hard disk. The audio sample is then processed using the DSP to create a reverb
effect. The processed audio sample is then written to the sun's audio device /dev/audio.
At the DSP side, the SwiftNet API is used for standard I/O functions such as fread() and
fwrite(). At the host side a virtual target is created using the API to allow the DSP access
to the hosts resources, specifically the file system and the audio device.
SwiftTools, Pentek's software development environment and debugging tools, uses the
API to communicate with the DSP target in a similar manner. The fundamental
difference is that SwiftTools is not a virtual target. It can initiate a data transfer to or from
the DSP target but does not need to respond to target initiated signals.
SwiftNet uses a small portion of the global memory to load the SwiftNet kernel. Specific
interrupt signals on the C30/C40/’C6x are also used by SwiftNet. Below is a list of global
memory addresses and C30/C40/’C6x interrupt signals which are reserved for the kernel
for each Pentek DSP board:
Rev. H
Pa ge 82 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
Please refer to the TI TMS320C30, TMS320C40, and TMS320C62x user's guide for further
information on the ‘C30, ‘C40, and ‘C6x signals.
Linker command file are provided for each boards architecture in the files:
swiftnet-x.x/42xx/lib/swiftnet.cmd
where: x.x is the SwiftNet revision and 42xx is the board type.
In cases where you want to use SwiftNet and simultaneously service ‘C6x
interrupts, you need to install a new handler. Since SwiftNet has its own
interrupt vector table and sets the Interrupt Service Table Pointer (ISTP), just
changing the ISTP would disable SwiftNet’s ability to handle the ‘C6x mailbox
interrupts.
To install a new handler, use the isr_jump_table array with the interrupt
you want to use. The ‘C6x provides 12 interrupts, INT4 through INT15. Refer
to the ‘C6x documentation for a complete description of each interrupt.
Rev. H
Sw i ft Net 3 .5 Ho st So f tw a re - Us er’s G u id e Pa ge A-1
There are four SwiftNet API examples in this section, APITARGET.C, APIHOST.C,
APITARGETX.C, and APIHOSTX.C.
These two API examples do not use the extended SwiftNet API features. The
program takes keyboard input from the host, sends it to the Swiftnet target,
which in turn sends back the information to the host, which displays the
keyboard input all using the SwiftNet communication channels.
These two SwiftNet API examples use the extended SwiftNet API features,
and perform the same task as the APITARGET.C and APIHOST.C, except
instead of using keyboard input, these examples use a data file as the input
source.
The SwiftNet Host Software is shipped with four demo programs; dim.c, dim69.c,
dim70.c, and reverb.c, which can be used to confirm an operating connection between
the host and the DSP target. These programs are contained in the /swiftnet-x.x/examples
directory and can be compiled using SwiftTools by setting the SWIFTTOOLS_PROJ to the
examples directory:
The program dim.c (contained in the subdirectory led-demo) drives the front
panel LED with a sinusoidally pulse-width modulated signal, causing the
brightness of the display to gradually increase and decrease. This program is
an endless-loop routine, and executes until you intervene.
Rev. H
Pa ge A -2 Sw i ft Ne t 3 .5 H o st So ft wa r e - Us er’s Gu i d e
A.2.2 DIM69.C & DIM 70.C - DIM69.C: code - page 17, DIM70.C: code - page 19
The programs dim69.c and dim70.c are written to run on the Pentek 4269 and
4270 VME boards respectively. When downloaded and started in all
processors on the board, this program drives the front panel LEDs associated
with each of the processors, with a sinusoidally pulse-width modulated
signal. The program should be loaded and started on processor 0 last. Again,
this is an endless-loop routine, and you must terminateit yourself.
REVERB.C was written for Sun SPARC workstations, but it can easily be
modified for Windows 95 and Windows NT.
The program reverb.c utilizes Sun's audio device. The program reads an audio
file from the Sun's hard drive, processes it using the DSP to add reverb, and
plays it back through the audio device. This program operates on an any of
the Pentek DSP boards.
Rev. H
/******************************************************************************
* FILE NAME: APITARGET.C
*
* VERSION DATA: $Archive: $
* $Revision: $
* $Modtime: $
* DESCRIPTION:
*
* Target end of SwiftNet API example
*
******************************************************************************/
/* $History: $
*/
#include "snio.h"
#include "pnkdev.h"
#include "pnkdapi.h"
#include "pnkcapi.h"
#define APISAMP_SIG 1
#define HOSTNAME "flanders" /* Name of machine where host end is
running */
#define DEVICENAME "apisamp" /* Virtual device name registered by
host */
u_int_32 _data[256];
u_int_32 _data_len;
c_int01()
{
PNK_SIGNAL_PTR sig;
PNK_RETURN_TYPE ret = {0,0,NULL};
u_int_32 i;
memcpy(_data,sig->data.data_val,sig->data.data_len);
_data_len = sig->data.data_len;
main()
{
PNK_DEVICE_TYPE dev;
PNKCAPI_TYPE pnkc;
PNK_SIGNAL_TYPE sig;
PNK_RETURN_TYPE ret;
char string[256];
code - Page 1
exit(1);
}
plog("target running");
while(1)
{
pnkd_pause(); /* Wait for SwiftNet signal */
sig.num = APISAMP_SIG;
sig.data.data_len = _data_len;
sig.timeout_ticks = TIMEOUT_TICKS;
sig.tick_ulen = TICK_ULEN;
pnkc_send(&pnkc,0,&sig,&ret);
}
}
code - Page 2
/******************************************************************************
* FILE NAME: APIHOST.C
*
* VERSION DATA: $Archive: $
* $Revision: $
* $Modtime: $
* DESCRIPTION:
*
* Host end of SwiftNet API example
*
******************************************************************************/
/* $History: $
*/
#include <stdio.h>
#include "pnkdev.h"
#include "pnkdapi.h"
#include "pnkcapi.h"
char _data[256];
handler()
{
PNK_SIGNAL_PTR sig;
PNK_RETURN_TYPE ret = {0,0,NULL};
u_int_32 i;
memcpy(_data,sig->data.data_val,sig->data.data_len * 4);
main()
{
PNK_DEVICE_TYPE dev;
PNK_DEVHDR_PTR devHdrPtr;
PNKCAPI_TYPE pnkc;
PNK_SIGNAL_TYPE sig;
PNK_RETURN_TYPE ret;
char string[256];
code - Page 3
{
printf("Error initializing client interface!\n");
exit(1);
}
dev.arch = "apisamp";
dev.parent = "";
dev.name = "apisamp";
dev.params.params_len = 0;
dev.params.params_val = 0;
if (pnkd_createDev(&dev) != OK)
{
printf("Error creating device\n");
exit(1);
}
while(1)
{
fgets(string,255,stdin);
if (string[0] == ’\n’)
exit(0);
sig.num = APISAMP_SIG;
sig.args.args_val = NULL;
sig.args.args_len = 0;
sig.timeout_ticks = TIMEOUT_TICKS;
sig.tick_ulen = TICK_ULEN;
code - Page 4
if ((strlen(string)%4) !=0)
sig.data.data_len + 1;
pnkc_send(&pnkc,0,&sig,&ret);
pnkd_pause();
fputs(_data,stdout);
}
}
code - Page 5
/******************************************************************************
* FILE NAME: APITARGETX.C
*
* VERSION DATA: $Archive: $
* $Revision: $
* $Modtime: $
* DESCRIPTION:
*
* Target end of SwiftNet API example, using extended size signals
*
******************************************************************************/
/* $History: $
*/
#include "snio.h"
#include "pnkdev.h"
#include "pnkdapi.h"
#include "pnkcapi.h"
u_int_32 *_data;
u_int_32 _data_len;
u_int_32 _data_sig = FALSE;
u_int_32 _terminate = FALSE;
/*****************************************************************************
FUNCTION NAME: c_int02 - shmalloc interrupt handler
ENTRY CONDITIONS: A SwiftNet signal # SHMALLOC_SIG was received
args_val[0] contains the size in long words to allocate
args_val[1] contains the section number
EXIT CONDITIONS: Shared memory is allocated using the shmalloc() function
call, and the pointer to the memory is returned in ret.val
*****************************************************************************/
c_int02()
{
static PNK_RETURN_TYPE ret = { 0L, 0L, NULL };
PNK_SIGNAL_PTR sig;
sig = pnkd_signal();
ret.val = shmalloc(sig->args.args_val[0],sig->args.args_val[1]);
pnkd_return(&ret);
_data_sig = FALSE;
}
code - Page 6
/*****************************************************************************
FUNCTION NAME: c_int03 - shmfree interrupt handler
ENTRY CONDITIONS: A SwiftNet signal # SHMFREE_SIG was received
args_val[0] contains a pointer to the shared memory,
previously returned by shmalloc.
EXIT CONDITIONS: Shared memory is freed up using the shmfree() function
call, and the return value is returned in ret.val
*****************************************************************************/
c_int03()
{
static PNK_RETURN_TYPE ret = { 0L, 0L, NULL };
PNK_SIGNAL_PTR sig;
sig = pnkd_signal();
ret.val = shmfree(sig->args.args_val[0]);
pnkd_return(&ret);
_data_sig = FALSE;
}
/*****************************************************************************
FUNCTION NAME: c_int04 - terminate signal interrupt handler
ENTRY CONDITIONS: A SwiftNet signal # TERMINATE_SIG was received
EXIT CONDITIONS: _data_sig is set to FALSE
_terminate is set to TRUE
*****************************************************************************/
c_int04()
{
static PNK_RETURN_TYPE ret = { 0L, 0L, NULL };
pnkd_return(&ret);
_terminate = TRUE;
_data_sig = FALSE;
}
/*****************************************************************************
FUNCTION NAME: c_int01 - Data interrupt handler
ENTRY CONDITIONS: A SwiftNet signal # APISAMP_SIG was received
EXIT CONDITIONS: Received data is copied to _data
The data length is long words is placed in _data_len
_data_sig is set to TRUE to indicate that a data signal
was received.
*****************************************************************************/
c_int01()
{
PNK_SIGNAL_PTR sig;
PNK_RETURN_TYPE ret = {0,0,NULL};
u_int_32 i;
memcpy(_data,sig->data.data_val,sig->data.data_len);
_data_len = sig->data.data_len;
code - Page 7
pnkd_return(&ret); /* Complete signal transaction, send empty return
data */
_data_sig = TRUE;
}
main()
{
PNK_DEVICE_TYPE dev;
PNKCAPI_TYPE pnkc;
PNK_SIGNAL_TYPE sig;
PNK_RETURN_TYPE ret;
char string[256];
code - Page 8
/* Open up a connection to virtual device existing on host */
plog("target running");
sig.num = HANDSHAKE_SIG;
sig.data.data_val = NULL;
sig.data.data_len = 0;
sig.args.args_len = 0;
sig.args.args_val = NULL;
while(1)
{
while (1)
{
pnkd_pause(); /* Wait for SwiftNet signal */
if (_data_sig | _terminate) break; /* If we received a data signal
or a terminate signal, some
additional processing needs
to be done */
}
sig.num = APISAMP_SIG;
sig.data.data_len = _data_len;
sig.timeout_ticks = TIMEOUT_TICKS;
sig.tick_ulen = TICK_ULEN;
pnkc_sendEx(&pnkc,0,&sig,&ret);
}
code - Page 9
/******************************************************************************
* FILE NAME: apihostx.c
*
* VERSION DATA: $Archive: $
* $Revision: $
* $Modtime: $
* DESCRIPTION:
*
* Host end of SwiftNet API example
*
******************************************************************************/
/* $History: $
*/
#include <stdio.h>
#include "pnkdev.h"
#include "pnkdapi.h"
#include "pnkcapi.h"
u_int_32 _data[XFERSIZE];
u_int_32 _data_len;
u_int_32 _ok = FALSE;
/*****************************************************************************
FUNCTION NAME: handler() - Data handler
ENTRY CONDITIONS: A SwiftNet signal # APISAMP_SIG was received
EXIT CONDITIONS: The received data is placed in _data
The received data length is placed in _data_len
*****************************************************************************/
handler()
{
PNK_SIGNAL_PTR sig;
PNK_RETURN_TYPE ret = {0,0,NULL};
u_int_32 i;
code - Page 10
sig = pnkd_signal(); /* Retreive signal */
memcpy(_data,sig->data.data_val,sig->data.data_len * 4);
_data_len = sig->data.data_len;
/*****************************************************************************
FUNCTION NAME: handshake() - Handshake signal handler
ENTRY CONDITIONS: A SwiftNet signal # HANDSHAKE_SIG was received
EXIT CONDITIONS: _ok is set to TRUE
*****************************************************************************/
handshake()
{
PNK_RETURN_TYPE ret = {0,0,NULL};
pnkd_return(&ret);
_ok = TRUE;
}
main()
{
PNK_DEVICE_TYPE dev;
PNK_DEVHDR_PTR devHdrPtr;
PNKCAPI_TYPE pnkc;
PNK_SIGNAL_TYPE sig,tmpsig;
PNK_RETURN_TYPE ret,tmpret;
FILE *fp;
u_int_32 size;
u_int_32 args[2];
u_int_32 data[XFERSIZE];
u_int_32 dpr_data;
dev.arch = "apisamp";
dev.parent = "";
dev.name = "apisamp";
dev.params.params_len = 0;
dev.params.params_val = 0;
if (pnkd_createDev(&dev) != OK)
{
printf("Error creating device\n");
exit(1);
}
code - Page 11
/* Connect signal handler, hander to signal number APISAMP_SIG */
fp = fopen(SENDFILE,"r");
tmpsig.num = SHMALLOC_SIG;
tmpsig.args.args_len = 2;
tmpsig.args.args_val = args;
tmpsig.data.data_len = 0;
tmpsig.data.data_val = NULL;
tmpsig.timeout_ticks = TIMEOUT_TICKS;
tmpsig.tick_ulen = TICK_ULEN;
dpr_data = tmpret.val;
while(1)
{
size = fread(data, 4, XFERSIZE, fp);
sig.num = APISAMP_SIG;
sig.args.args_val = NULL;
sig.args.args_len = 0;
sig.timeout_ticks = TIMEOUT_TICKS;
code - Page 12
sig.tick_ulen = TICK_ULEN;
pnkd_pause();
fwrite(_data,4,_data_len,stdout);
fclose(fp);
tmpsig.num = SHMFREE_SIG;
tmpsig.args.args_len = 2;
tmpsig.args.args_val = args;
tmpsig.data.data_len = 0;
tmpsig.data.data_val = NULL;
tmpsig.timeout_ticks = TIMEOUT_TICKS;
tmpsig.tick_ulen = TICK_ULEN;
args[0] = dpr_data;
tmpsig.num = TERMINATE_SIG;
tmpsig.args.args_len = 0;
tmpsig.args.args_val = NULL;
tmpsig.data.data_len = 0;
tmpsig.data.data_val = NULL;
tmpsig.timeout_ticks = TIMEOUT_TICKS;
tmpsig.tick_ulen = TICK_ULEN;
code - Page 13
/******************************************************************************
*
*
* FILE NAME: dim.c
*
*
******************************************************************************/
/******************************************************************************/
/******************************************************************************/
#include <math.h>
/******************************************************************************/
#define PI 3.141592654
/******************************************************************************/
/******************************************************************************/
main()
{
double angle;
int onDelay, offDelay;
int cnt = 0;
#if JTAG_TEST
asm(" ANDN 2000h,ST");
#endif
while(1){
for(angle = 0.0;
cnt++;
onDelay = (fullDuty / 2.0) * (sin(angle) + 1.0);
offDelay = fullDuty - onDelay;
ledOn();
wait(onDelay);
ledOff();
wait(offDelay);
}
}
}
/******************************************************************************/
ledOn()
code - Page 14
{
#ifdef ARCH_4283
asm(" ldi 6,iof"); /* turn LED on */
#endif
#ifdef ARCH_4284
*((volatile unsigned long *)0x90000000) |= 0x40;
#endif
#ifdef ARCH_4280
*((volatile unsigned long *)0x500000) &= ~0x200;
#endif
#ifdef ARCH_4270
*((volatile unsigned long *)0x100020) &= ~0x5;
*((volatile unsigned long *)0x100020) |= 0x2;
#endif
#ifdef ARCH_4285
*((volatile unsigned long *)0x00380000) &= ~0x80;
#endif
#ifdef ARCH_4288
unsigned long systat;
#ifdef ARCH_4290
*((volatile unsigned int *)0x28001c) |= 0x8;
#endif
/******************************************************************************/
ledOff()
#ifdef ARCH_4283
asm(" ldi 2,iof"); /* turn LED off */
#endif
#ifdef ARCH_4284
*((volatile unsigned long *)0x90000000) &= ~0x40;
#endif
#ifdef ARCH_4280
*((volatile unsigned long *)0x500000) |= 0x200;
#endif
#ifdef ARCH_4270
*((volatile unsigned long *)0x100020) &= ~0x1;
*((volatile unsigned long *)0x100020) |= 0x6;
#endif
#ifdef ARCH_4285
*((volatile unsigned long *)0x00380000) |= 0x80;
#endif
code - Page 15
#ifdef ARCH_4288
unsigned long systat;
#ifdef ARCH_4290
*((volatile unsigned int *)0x28001c) &= (~0x8);
#endif
/******************************************************************************/
wait(count)
int count;
{
int i;
#if CACHE_TEST
asm(" OR 800h,ST"); /* enable cache */
#endif
/******************************************************************************/
code - Page 16
/******************************************************************************
*
*
* FILE NAME: dim69.c
*
*
******************************************************************************/
#include <math.h>
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
main()
{
if(((*PROC_ID & 0x300000) == 0) || ((*PROC_ID & 0x300000) == 0x300000))
{
procAD(); /* processor A/D routine */
}
else
{
procBC(); /* processor B/C routine */
}
}
/*****************************************************************************/
procAD()
{
double angle;
int onDelay, offDelay;
while(1)
{
for(angle = 0.0;
angle <= 2 * PI;
angle = angle + (2 * PI / angleSteps))
{
onDelay = (fullDuty / 2.0) * (sin(angle) + 1.0);
offDelay = fullDuty - onDelay;
code - Page 17
while((*COM0_CTRL & 0x1e0) != 0x0); /* wait for COM0 output
*/
*COM0_OUTPUT = LED_OFF; /* turn proc B LED off *
/
wait(onDelay);
wait(offDelay);
}
}
}
/*****************************************************************************/
wait(count)
int count;
{
int i;
for(i = 0; i < count; i++);
}
/*****************************************************************************/
procBC()
{
while(1)
{
while((*COM3_CTRL & 0x1e00) == 0x0); /* wait for COM3 input */
*TIMER0_CTRL = *COM3_INPUT; /* turn LED on or off */
}
}
/*****************************************************************************/
code - Page 18
/******************************************************************************
*
*
* FILE NAME: dim70.c
*
*
******************************************************************************/
#include <math.h>
/*****************************************************************************/
#define PROC_ID ((unsigned long *)0x340000)
#define TIMER0_CTRL ((unsigned long *)0x100020)
#define LED_ON 0x302
#define LED_OFF 0x306
#define COM0_CTRL ((volatile unsigned long *)0x100040)
#define COM0_INPUT ((unsigned long *)0x100041)
#define COM0_OUTPUT ((unsigned long *)0x100042)
#define COM1_CTRL ((volatile unsigned long *)0x100050)
#define COM1_INPUT ((unsigned long *)0x100051)
#define COM1_OUTPUT ((unsigned long *)0x100052)
#define COM3_CTRL ((volatile unsigned long *)0x100070)
#define COM3_INPUT ((unsigned long *)0x100071)
#define COM3_OUTPUT ((unsigned long *)0x100072)
#define COM4_CTRL ((volatile unsigned long *)0x100080)
#define COM4_INPUT ((unsigned long *)0x100081)
#define COM4_OUTPUT ((unsigned long *)0x100082)
#define PI 3.1415927
/*****************************************************************************/
/*****************************************************************************/
main()
{
int id;
id = (*(PROC_ID) >> 20) & 0x3;
switch(id)
{
case 0:
procA(); /* processor A */
case 1:
procB(); /* processor B */
case 2:
procC(); /* processor C */
case 3:
procD(); /* processor D */
}
}
/*****************************************************************************/
procA()
{
double angle;
int onDelay, offDelay;
while(1)
{
for(angle = 0.0;
angle <= 2 * PI;
code - Page 19
angle = angle + (2 * PI / angleSteps))
{
onDelay = (fullDuty / 2.0) * (sin(angle) + 1.0);
offDelay = fullDuty - onDelay;
*TIMER0_CTRL = LED_ON; /* turn proc A LED on */
while((*COM0_CTRL & 0x1e0) != 0x0); /* wait for COM0 output */
*COM0_OUTPUT = LED_OFF; /* turn proc B LED off */
while((*COM1_CTRL & 0x1e0) != 0x0); /* wait for COM1 output */
*COM1_OUTPUT = LED_ON /* turn proc D LED on */
while((*COM3_CTRL & 0x1e0) != 0x0); /* wait for COM3 output */
*COM3_OUTPUT = /* turn proc C LED off */
wait(onDelay);
*TIMER0_CTRL = LED_OFF; /* turn proc A LED off */
while((*COM0_CTRL & 0x1e0) != 0x0); /* wait for COM0 output */
*COM0_OUTPUT = LED_ON; /* turn proc B LED on */
while((*COM1_CTRL & 0x1e0) != 0x0); /* wait for COM1 output */
*COM1_OUTPUT = LED_OFF; /* turn proc D LED off */
while((*COM3_CTRL & 0x1e0) != 0x0); /* wait for COM3 output */
*COM3_OUTPUT = LED_ON; /* turn proc C LED on */
wait(offDelay);
}
}
}
/****************************************************************************/
wait(count)
int count;
{
int i;
for(i = 0; i < count; i++);
}
/*****************************************************************************/
procB()
{
while(1)
{
while((*COM3_CTRL & 0x1e00) == 0x0) /* wait for COM3 input */
*TIMER0_CTRL = *COM3_INPUT; /* turn LED on or off */
}
}
/*****************************************************************************/
procC()
{
while(1)
{
while((*COM0_CTRL & 0x1e00) == 0x0); /* wait for COM0 input */
*TIMER0_CTRL = *COM0_INPUT; /* turn LED on or off */
}
}
/*****************************************************************************/
code - Page 20
procD()
{
while(1)
{
while((*COM4_CTRL & 0x1e00) == 0x0);
/* wait for COM4 input */
*TIMER0_CTRL = *COM4_INPUT; /* turn LED on or off */
}
}
/*****************************************************************************/
code - Page 21
/******************************************************************************
*
*
* FILE NAME: reverb.c
*
*
******************************************************************************/
#include <stdlib.h>
#include <snstdio.h>
/******************************************************************************/
/******************************************************************************/
#ifdef MACH_C6X
unsigned char linear2ulaw(/* int */);
int ulaw2linear(/* unsigned char */);
#ifdef MACH_21060
#define uLawCmp mu_compress
#define uLawExp mu_expand
#endif
/******************************************************************************/
main()
{
static char buf[BUFSIZ];
static float rvBuf[SAMP_RATE];
FILE *auFile, *auDev;
float delay, gain, tmp, input, output;
int rvLen, rvIndex, extraIter, extraSamp;
unsigned data;
/*
* initialize standard I/O
*/
if(snstdio_init(HOST_NAME) != OK){
plog("snstdio_init() failed!");
return(-1);
}
atexit((void (*)())snstdio_shutdown);
code - Page 22
/*
* chdir to sound directory
*/
if(chdir(SOUND_DIR) != 0){
printf("Sound directory does not exist: %s\n", SOUND_DIR);
}
/*
* list sound files
*/
printf("Audio files:\n\n");
system("ls *.au");
/*
* continue to read files until the user exits
*/
while(1){
/*
* get/open audio file
*/
gets(buf);
if(strlen(buf) == 0){
break;
}
/*
* get delay length, calculate buffer length
*/
/*
code - Page 23
* initialize buffer
*/
/*
* get feedback gain
*/
/*
* calculate how long to continue to play after input ends
*/
tmp = gain;
extraIter = 1;
while(tmp > OUTPUT_THRSHLD){
tmp = tmp * gain;
extraIter++;
}
/*
* open audio device
*/
printf("\n\nOpening /dev/audio...");
fflush(stdout);
printf("done.\n");
/*
* do it!
*/
data = getw(auFile);
while(!feof(auFile)){
input = uLawExp(data);
output = input + rvBuf[rvIndex];
rvBuf[rvIndex] = output * gain;
rvIndex = (rvIndex + 1) % rvLen;
putw(uLawCmp((int)output), auDev);
data = getw(auFile);
}
code - Page 24
/*
* generate extra output to allow signal to decay
*/
printf("done.\n");
printf("Closing /dev/audio...");
fflush(stdout);
fclose(auDev);
printf("done.\n");
printf("bye!\n");
}
/******************************************************************************/
code - Page 25
/******************************************************************************
*
* File Name: ipfifo.c
*
* DESCRIPTION:
*
* Simple example of using the interprocessor FIFOs and interrupts
* Processor 0 will write a count between 0 and 3 to the IP Fifo. After
* the almost full threshold has been reached, an interrupt will be received
* by processor 1, which will read the data from the IP Fifo, and flash the
* corresponding LED.
*
*****************************************************************************/
#define RESET 0
#define NMI 1
#define INT4 4
#define INT5 5
#define INT6 6
#define INT7 7
#define INT8 8
#define INT9 9
#define INT10 10
#define INT11 11
#define INT12 12
#define INT13 13
#define INT14 14
#define INT15 15
/* Board registers */
/* Processor registers */
/*****************************************************************************
FUNCTION NAME: handler() - Simple interrupt handler
ENTRY CONDITIONS: A processor INT7 has been received
EXIT CONDITIONS: a LED is flashed coresponding to data read from the IP fifo.
Handler returns when there is no more data in FIFO.
RETURNS: nothing
CAVEATS: none known
*****************************************************************************/
code - Page 26
interrupt void handler()
{
*IFR1 = 0x400; /* Clear almost full flag*/
ICR = 0x80; /* Clear C6X INT7 */
while(!((*ISR1) & 0x100)) /* Read data while the FIFO is not empty */
flash(*FIFO,1); /* flash led coresponding to data read */
}
main()
{
int count;
volatile unsigned int temp;
/* Note, the processor codes used here, to detect the processor # only
apply to four processor boards. This will have to be changed if using
a two processor board */
delay(1000);
while(1)
{
for (count = 0;count < 4;count++)
{
*FIFO = count; /* Write to FIFO */
flash(count,1);
}
}
}
CSR |= 1; /* GIE = 1 */
code - Page 27
*IER1 |= 0x400; /* Enable almost full interrupt */
while (1)
asm(" idle"); /* Wait for interrupt */
}
/*****************************************************************************
FUNCTION NAME: flash() - flash a specified LED a specified number of times
ENTRY CONDITIONS: led = LED number to flash; count = number of times to flash
EXIT CONDITIONS: none
RETURNS: nothing
CAVEATS: none known
*****************************************************************************/
delay(500);
delay(500);
}
}
code - Page 28
/*****************************************************************************
FUNCTION NAME: delay() - Simple loop delay
ENTRY CONDITIONS: len = number of iterations of outside loop
EXIT CONDITIONS: none
RETURNS: nothing
CAVEATS: delay is dependent on processor clock speed
*****************************************************************************/
delay(int len)
{
int count,count2;
code - Page 29
This page is intentionally blank