1061 lines
70 KiB
HTML
1061 lines
70 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||
"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
|
||
<html lang="en">
|
||
<head>
|
||
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
|
||
<title>GPIF</title>
|
||
<meta name="generator" content="BBEdit 6.0">
|
||
<script language="JavaScript">
|
||
<!--
|
||
function na_preload_img()
|
||
{
|
||
var img_list = na_preload_img.arguments;
|
||
if (document.preloadlist == null)
|
||
document.preloadlist = new Array();
|
||
var top = document.preloadlist.length;
|
||
for (var i=0; i < img_list.length; i++) {
|
||
document.preloadlist[top+i] = new Image;
|
||
document.preloadlist[top+i].src = img_list[i+1];
|
||
}
|
||
}
|
||
|
||
function na_change_img_src(name, nsdoc, rpath, preload)
|
||
{
|
||
var img = eval((navigator.appName.indexOf('Netscape', 0) != -1) ? nsdoc+'.'+name : 'document.all.'+name);
|
||
if (name == '')
|
||
return;
|
||
if (img) {
|
||
img.altsrc = img.src;
|
||
img.src = rpath;
|
||
}
|
||
}
|
||
|
||
// -->
|
||
</script>
|
||
</head>
|
||
<body bgcolor="#FFFFFF" OnLoad="na_preload_img(false, 'images/dsp-cp1.gif', 'images/dsp-cp2.gif', 'images/dsp-cp3.gif');">
|
||
|
||
|
||
<table border="0" cellpadding="0" cellspacing="0" width="90%" align="center">
|
||
<tr valign="top">
|
||
<td colspan="1" align="left">
|
||
|
||
<p align="center"><font face="verdana, arial, helvetica, sans-serif" size="2" color="#000000"><B><a name="SingleXactions"></a>Implementing GPIF Transactions</B></font>
|
||
</td>
|
||
</tr>
|
||
|
||
<tr valign="top">
|
||
<td colspan="1" align="left">
|
||
|
||
<p>
|
||
|
||
<font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000"><br>
|
||
</font>
|
||
</td>
|
||
</tr>
|
||
|
||
<tr valign="top">
|
||
<td colspan="1" align="left">
|
||
<p><font face="Verdana" size="1"><b><a name="WaveformDescriptors"></a>Creating
|
||
GPIF Waveform
|
||
Descriptors using GPIF Designer<br> </b></font></p>
|
||
</td>
|
||
</tr>
|
||
<tr valign="top">
|
||
<td colspan="1" align="left">
|
||
|
||
<p align="center">
|
||
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td colspan="1" align="center">
|
||
<p align="left"><font face="Verdana" size="1">In order to design
|
||
the GPIF waveform descriptors for this example, it is first important
|
||
to understand a little bit about how the TI DSP’s HPI protocol works.
|
||
Each HPI transfer is a two-byte sequence. The meaning of the first
|
||
byte and second byte depends on how the BOB bit is set in the DSP’s
|
||
HPIC register. In our example, the BOB bit is set to 1, which means
|
||
that the first byte of the HPI transfer is going to be the LSB and
|
||
the second byte of the transfer is going to be the MSB (as organized
|
||
in the DSP memory).</font></p>
|
||
<p align="left"><font face="Verdana" size="1">The example uses GPIF
|
||
single write transactions for writing to the HPIC and HPIA registers,
|
||
GPIF FIFO Write transactions for writing data into the HPI RAM,
|
||
and GPIF FIFO Read transactions for reading data from the HPI RAM.
|
||
Writing to the HPIC and HPIA registers is a special case that requires
|
||
two separate waveform behaviors to describe the entire HPI transfer.
|
||
One waveform behavior describes the timing and control logic for
|
||
the first byte of the HPI transfer, and another describes the timing
|
||
and control logic for the second byte of the HPI transfer.</font></p>
|
||
<p align="left"><font face="Verdana" size="1">In all of the GPIF
|
||
waveforms, CTL0-2 are manipulated according to the HPI protocol
|
||
and the HPI8 Mode Timing Requirements as outlined in the 5416 data
|
||
sheet. In the text to follow, we will discuss how CTL0-2 were manipulated
|
||
in the GPIF waveforms to describe the HPI protocol. <i>Figure 23</i>
|
||
shows the block diagram for the DSP example.</font></p>
|
||
<p align="center"><font face="Verdana" size="1"><img src="images/blockdiag.gif" width="432" height="327" border="0"><br>Figure
|
||
23. GPIF Designer Block Diagram View</font></p>
|
||
<p align="left"><font face="Verdana" size="1"><i>Figure 24,</i>
|
||
below, shows waveform 0, which characterizes the behavior of the
|
||
waveform called SnglWr1. SnglWr1 describes the HPI protocol required
|
||
to write the first byte of an HPI transfer.<br></font></p>
|
||
<p align="center"><font face="Verdana" size="1"><img src="images/DSPSingleWr1.gif" width="432" height="327" border="0"><br>Figure
|
||
24. SnglWr1 waveform in GPIF Designer<br></font></p>
|
||
<p align="left"><font face="Verdana" size="1">Since SnglWr1 describes
|
||
an HPI write operation, HR/W (CTL0) is held LOW throughout the entire
|
||
transfer (S0-S2). HBIL (CTL2) is dropped LOW in S0 to signify that
|
||
the first byte is being transferred. This is done before HDS1 (CTL1)
|
||
is asserted in S1, in order to satisfy the set-up time requirement
|
||
for HBIL before HDS1 can be made LOW. Since S0 is active for 20.83
|
||
ns (Wait 1 at 48-MHz IFCLK), this satisfies the set-up time requirement
|
||
of 6 ns for HBIL. Since there is also a hold time requirement for
|
||
HBIL, to simplify matters, HBIL is actually held LOW throughout
|
||
the active portion of the entire waveform.</font></p>
|
||
<p align="left"><font face="Verdana" size="1">By looking at the
|
||
HPI8 Timing Requirements in the 5416 data sheet, it becomes apparent
|
||
that any of the strobe widths or set-up and hold times are well
|
||
under 20.83 ns. Therefore, one can assume that a state need only
|
||
last at maximum 20.83 ns (Wait 1). In S1, data is also placed on
|
||
the bus (Activate Data). In S2, HDS1 is deasserted, thus ending
|
||
this portion of the HPI transfer. S2 also unconditionally branches
|
||
to the IDLE state to terminate the waveform.</font></p>
|
||
<p align="left"><font face="Verdana" size="1">The waveform that
|
||
describes the second portion of the HPI transfer is very similar
|
||
to SnglWr1, and is shown in <i>Figure 25</i>.<br></font></p>
|
||
<p align="center"><font face="Verdana" size="1"><img src="images/DSPSingleWr2.gif" width="432" height="327" border="0"><br>Figure
|
||
25. SnglWr2 waveform in GPIF Designer</font></p>
|
||
<p align="left"><font face="Verdana" size="1">Again, since SnglWr2
|
||
also describes an HPI write operation, HR/W is held LOW throughout
|
||
the entire active portion of the waveform (S0–S2). The main difference
|
||
between SnglWr2 and SnglWr1 is the state of HBIL; HBIL is HIGH throughout
|
||
S0–S2. This signifies to the HPI that the second byte of the HPI
|
||
transfer is being transmitted. S2 unconditionally branches to the
|
||
IDLE state to terminate the waveform.</font></p>
|
||
<p align="left"><font face="Verdana" size="1">To recap, the SnglWr1
|
||
and SnglWr2 waveforms are used for GPIF single write accesses, which
|
||
allow us to write to the DSP’s HPIC/HPIA registers. The GPIF engine
|
||
allows you to select which of these waveforms are triggered by a
|
||
GPIF single write access, via the GPIFWFSELECT register. Consecutive
|
||
GPIF single write accesses using the waveforms SnglWr1 and SnglWr2
|
||
are made to describe the entire HPI transfer protocol. The details
|
||
of this are described in the firmware programming section (4.2.5).</font></p>
|
||
<p align="left"><font face="Verdana" size="1">To create the GPIF
|
||
FIFO read and write accesses that handle writing and reading to
|
||
and from the HPI data RAM, the attributes of the SnglWr1 and SnglWr2
|
||
waveforms can be combined to form each of the GPIF FIFO read and
|
||
write waveforms. <i>Figure 26</i> shows the GPIF FIFO write waveform.<br></font></p>
|
||
<p align="center"><font face="Verdana" size="1"><img src="images/DSPFifoWr.gif" width="432" height="327" border="0"><br>Figure
|
||
26. FIFOWr waveform in GPIF Designer</font></p>
|
||
<p align="left"><font size="1" face="Verdana">Waveform 3 (FIFOWr)
|
||
describes an entire HPI write transfer. S0 drives both HR/W and
|
||
HBIL LOW for 20.83 ns, then S1 asserts HDS1 and drives the data
|
||
bus to present the first byte in the EP2 FIFO, effectively writing
|
||
out the first byte of the HPI transfer to the HPI RAM. S2 then increments
|
||
the FIFO pointer using Next FIFO data, deasserts HDS1, and drives
|
||
HBIL HIGH to tell the HPI the second byte of the transfer is coming.
|
||
S3 asserts HDS1 again and drives the data bus to present the second
|
||
byte in the EP2 FIFO, effectively writing out the second byte of
|
||
the HPI transfer to the HPI RAM.</font></p>
|
||
<p align="left"><font size="1" face="Verdana">The waveform then
|
||
traverses to S5, a decision point state that examines the GPIF TC
|
||
to determine whether or not to branch to the IDLE state. If the
|
||
GPIF TC has not yet expired, the waveform will then branch back
|
||
to S0 to actuate another HPI transfer. Otherwise, the waveform branches
|
||
to the IDLE state and terminates. The FIFO read waveform is quite
|
||
similar in nature and is shown in <i>Figure 27</i>.<br></font></p>
|
||
<p align="center"><font face="Verdana" size="1"><img src="images/DSPFifoRd.gif" width="432" height="327" border="0"><br>Figure
|
||
27. FIFORd waveform in GPIF Designer</font></p>
|
||
<p align="left"><font size="1" face="Verdana">Waveform 2 (FIFORd)
|
||
describes an entire HPI read transfer. HR/W is driven HIGH throughout
|
||
the waveform to tell the HPI that this is a read operation. In S0,
|
||
HBIL is driven LOW for 20.83 ns to satisfy the set-up time requirement
|
||
for HBIL, then S1 asserts HDS1, which tells the HPI to present the
|
||
first byte of the HPI read transfer onto the data bus. The data
|
||
is not presented until 10ns later, therefore it is correct to only
|
||
sample the databus in S2 and not in S1. By sampling the databus
|
||
in S2, the first byte is read into the FX2’s EP6 FIFO. For a GPIF
|
||
FIFO read transaction, an Activate Data also advances the FIFO pointer,
|
||
so a Next FIFO data is not necessary.</font></p>
|
||
<p align="left"><font size="1" face="Verdana">S2 also drives HBIL
|
||
HIGH to tell the HPI the second byte of the transfer is expected.
|
||
S3 asserts HDS1 again and S4 samples the data bus to read the second
|
||
byte into the EP6 FIFO.</font></p>
|
||
<p align="left"><font size="1" face="Verdana">The waveform then
|
||
traverses to S5, a decision point state that examines the GPIF TC
|
||
to determine whether or not to branch to the IDLE state. If the
|
||
GPIF TC has not yet expired, the waveform will then branch back
|
||
to S0 to actuate another HPI read transfer. Otherwise, the waveform
|
||
branches to the IDLE state and terminates.</font></p>
|
||
<p align="left"><font size="1" face="Verdana">Now that you understand
|
||
how the GPIF waveforms are programmed and set up for the DSP example,
|
||
the firmware programming can be discussed.<br> </font></p>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td colspan="1" align="center" height="13">
|
||
<p align="left"><font face="Verdana" size="1"><b><a name="FW"></a>Firmware</b></font></p>
|
||
</td>
|
||
</tr>
|
||
<tr valign="top">
|
||
<td colspan="1" align="left">
|
||
<p>
|
||
<font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">After the GPIF waveforms were implemented using
|
||
GPIF Designer, the next step was to integrate the USB portion of the overlying
|
||
firmware with the GPIF Designer output to perform write and read operations to and from the HPI. To do this a firmware frameworks
|
||
project was copied and the code that performed the HPI operations was added to the TD_Poll() function within
|
||
FX2_to_TI5416_HPI.c (note that periph.c was renamed to something more meaningful here). Endpoint and GPIF register initialization
|
||
is performed in the TD_Init() function, which is also within FX2_to_TI5416_HPI.c.<br>
|
||
<br><br><a name="Files"></a>When the user opens up the Keil uVision2
|
||
project for the DSP example, Figure 17 shows the list of files that should be seen in the Project Window:</font> </td>
|
||
</tr>
|
||
|
||
<tr valign="top">
|
||
<td colspan="1" align="center">
|
||
|
||
<p align="center"><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">
|
||
<img src="images/dsp-keil.gif" width="288" height="168" align="center" border="0" ismap usemap="#keil_map"><br>
|
||
Figure 17<br>
|
||
</font> <ul>
|
||
<p align="left"><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">The
|
||
contents of these files is as follows: <br>
|
||
</font></p>
|
||
</ul>
|
||
|
||
</td>
|
||
</tr>
|
||
|
||
<tr>
|
||
<td colspan="1" align="center" height="15">
|
||
<ul>
|
||
<p align="left"><font face="Verdana" size="1"><b>fw.c</b><br>Firmware
|
||
frameworks which handles USB requests and calls the task dispatcher
|
||
TD_Poll(). </font></p>
|
||
</ul>
|
||
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td colspan="1" align="center" height="15">
|
||
<ul>
|
||
<p align="left"><font face="Verdana" size="1"><b>Ezusb.lib</b><br>Collection
|
||
of functions that handle suspend, resume, I2C operations, etc. </font></p>
|
||
</ul>
|
||
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td colspan="1" align="center" height="15">
|
||
<ul>
|
||
<p align="left"><font face="Verdana" size="1"><b>USBJmpTb.OBJ</b><br>Interrupt
|
||
vector jump table for USB (INT2) and GPIF/Slave FIFO (INT4)
|
||
interrupt sources. </font></p>
|
||
</ul>
|
||
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td colspan="1" align="center" height="15">
|
||
<ul>
|
||
<p align="left"><font face="Verdana" size="1"><b>dscr.a51</b><br>Device
|
||
descriptor tables for the DSP example which report EP2OUT and
|
||
EP6IN as available endpoints for the FX2 device. EP1IN and EP1OUT
|
||
are also reported although they are not used in this example.
|
||
These low bandwidth endpoints may be used for general purpose
|
||
should the need arise in an application. </font></p>
|
||
</ul>
|
||
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td colspan="1" align="center" height="15">
|
||
<ul>
|
||
<p align="left"><font face="Verdana" size="1"><b>gpif.c</b><br>File
|
||
that contains the GPIF waveform descriptor tables that implement
|
||
the DSP GPIF transaction waveform behavior.</font></p>
|
||
</ul>
|
||
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td colspan="1" align="center" height="15">
|
||
<ul>
|
||
<p align="left"><font face="Verdana" size="1"><b>FX2_to_extsyncFIFO.c</b><br>Main
|
||
user application code where TD_Poll() and TD_Init() can be found.
|
||
The user will mainly be modifying this particular file and will
|
||
not need to touch fw.c.</font></p>
|
||
</ul>
|
||
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td colspan="1" align="center" height="15">
|
||
<ul>
|
||
<p align="left"><font face="Verdana" size="1"><b>int0.c</b><br>File
|
||
that contains the interrupt service routine for servicing the
|
||
INT0/ interrupt. </font></p>
|
||
</ul>
|
||
</td>
|
||
</tr>
|
||
<tr valign="top">
|
||
<td colspan="1" align="left">
|
||
|
||
<ul>
|
||
<font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000"><B><a name="TD_Init("></a>TD_Init( )</B>
|
||
</font>
|
||
</ul>
|
||
|
||
</td>
|
||
</tr>
|
||
|
||
<tr valign="top">
|
||
<td colspan="1" align="left">
|
||
<ul>
|
||
|
||
<p>
|
||
<font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">The first task at hand was to setup the endpoints appropriately for this example. The following code switches the CPU clock speed
|
||
to 48 MHz (since at power-on default it is 12 MHz), and sets up EP2 as a Bulk OUT endpoint, 4x buffered of size 512, and EP6
|
||
as a Bulk IN endpoint, also 4x buffered of size 512. This setup utilizes the maximum allotted 4 KB FIFO space. It also sets up the
|
||
FIFOs for auto mode, byte wide operation, and goes through a FIFO reset and arming sequence to ensure that they are ready
|
||
for data operations. EP1IN and EP1OUT are also setup in case the application needs them, although they are not used by this
|
||
example.<br>
|
||
</font>
|
||
</ul>
|
||
</td>
|
||
</tr>
|
||
|
||
<tr valign="top">
|
||
<td colspan="1" align="left">
|
||
<blockquote>
|
||
<ul>
|
||
<font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000"><font color="#339933">// set the CPU clock to 48MHz</font><br>
|
||
CPUCS = ((CPUCS & ~bmCLKSPD) | bmCLKSPD1);<br>
|
||
<font color="#666666">SYNCDELAY</font>;<br>
|
||
<br>
|
||
EP1OUTCFG = <font color="#0000CC">0xA0</font>; <font color="#339933">// always OUT, valid, bulk</font><br>
|
||
<font color="#666666">SYNCDELAY</font>;<br>
|
||
EP1INCFG = <font color="#0000CC">0xA0</font>; <font color="#339933">// always IN, valid, bulk</font><br>
|
||
<font color="#666666">SYNCDELAY</font>;<br>
|
||
EP2CFG = <font color="#0000CC">0xA0</font>; <font color="#339933">// EP2OUT, bulk, size 512, 4x buffered</font><br>
|
||
<font color="#666666">SYNCDELAY</font>;<br>
|
||
EP4CFG = <font color="#0000CC">0x00</font>; <font color="#339933">// EP4 not valid</font><br>
|
||
<font color="#666666">SYNCDELAY</font>;<br>
|
||
<br>
|
||
EP6CFG = <font color="#0000CC">0xE0</font>; <font color="#339933">// EP6IN, bulk, size 512, 4x buffered</font><br>
|
||
<font color="#666666">SYNCDELAY</font>;<br>
|
||
EP8CFG = <font color="#0000CC">0x00</font>; <font color="#339933">// EP8 not valid</font><br>
|
||
<font color="#666666">SYNCDELAY</font>;<br>
|
||
<br>
|
||
FIFORESET = <font color="#0000CC">0x80</font>; <font color="#339933">// set NAKALL bit to NAK all transfers from host</font><br>
|
||
<font color="#666666">SYNCDELAY</font>;<br>
|
||
FIFORESET = <font color="#0000CC">0x02</font>; <font color="#339933">// reset EP2 FIFO</font><br>
|
||
<font color="#666666">SYNCDELAY</font>;<br>
|
||
FIFORESET = <font color="#0000CC">0x06</font>; <font color="#339933">// reset EP6 FIFO</font><br>
|
||
<font color="#666666">SYNCDELAY</font>;<br>
|
||
FIFORESET = <font color="#0000CC">0x00</font>; <font color="#339933">// clear NAKALL bit to resume normal operation</font><br>
|
||
<font color="#666666">SYNCDELAY</font>;<br>
|
||
<br>
|
||
EP2FIFOCFG = <font color="#0000CC">0x00</font>; <font color="#339933">// allow core to see zero to one transition of auto out bit</font><br>
|
||
<font color="#666666">SYNCDELAY</font>;<br>
|
||
EP2FIFOCFG = <font color="#0000CC">0x10</font>; <font color="#339933">// auto out mode, disable PKTEND zero length send, byte ops</font><br>
|
||
<font color="#666666">SYNCDELAY</font>;<br>
|
||
EP6FIFOCFG = <font color="#0000CC">0x08</font>; <font color="#339933">// auto in mode, disable PKTEND zero length send, byte ops</font><br>
|
||
<font color="#666666">SYNCDELAY</font>;<br>
|
||
EP1OUTBC = <font color="#0000CC">0x00</font>; <font color="#339933">// arm EP1OUT by writing any value to EP1OUTBC register</font><br>
|
||
<font color="#666666">SYNCDELAY</font>;<br>
|
||
<br>
|
||
GpifInit (); <font color="#339933">// initialize GPIF registers</font><br>
|
||
<br>
|
||
PORTACFG = bmBIT0; <font color="#339933">// initialize PA3 and PA2 port i/o pins as outputs,</font><br>
|
||
OEA |= <font color="#0000CC">0x0C</font>; <font color="#339933">// PA0 takes on INT0/ alternate function</font><br>
|
||
<br>
|
||
EX0 = <font color="#0000CC">1</font>; <font color="#339933">// Enable INT0/ interrupt</font><br>
|
||
IT0 = <font color="#0000CC">1</font>; <font color="#339933">// Detect INT0/ on falling edge</font><br> <br></font>
|
||
</ul>
|
||
|
||
</blockquote>
|
||
</font>
|
||
</td>
|
||
</tr>
|
||
|
||
<tr valign="top">
|
||
<td colspan="1" align="left">
|
||
|
||
<ul>
|
||
<font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000"><B><a name="IFCONFIG"></a>IFCONFIG Register</B><br>
|
||
|
||
</font>
|
||
</ul>
|
||
|
||
</td>
|
||
</tr>
|
||
|
||
<tr valign="top">
|
||
<td colspan="1" align="left">
|
||
<ul>
|
||
|
||
<p>
|
||
<font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">TD_Init then calls the function GPIFInit() which resides in gpif.c. GPIFInit() is where the loading of the GPIF waveform descriptor
|
||
table into on-chip memory takes place and other GPIF registers get setup. An important register, IFCONFIG, also gets setup here
|
||
to define how the physical interface operates. Table 4 goes through the reasoning behind the setup of the IFCONFIG register for
|
||
this example.<br>
|
||
<br>
|
||
The last thing TD_Init does is it setups up PA3 and PA2 as outputs and enables the INT0/ functionality.<br>
|
||
</font>
|
||
</ul>
|
||
</td>
|
||
</tr>
|
||
|
||
<tr valign="top">
|
||
<td colspan="1" align="center">
|
||
<table align="center" border="1" cellspacing="0" width="90%" bordercolordark="white" bordercolorlight="black">
|
||
<tr>
|
||
<td width="38" height="15">
|
||
<p align="center"><font face="Verdana" size="1"><b>Bit
|
||
#</b></font></p>
|
||
</td>
|
||
<td width="79" height="15">
|
||
<p align="center"><font face="Verdana" size="1"><b>Bit
|
||
Label</b></font></p>
|
||
</td>
|
||
<td width="547" height="15">
|
||
<p align="center"><font face="Verdana" size="1"><b>Contents
|
||
/ Description</b></font></p>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td width="38" height="13">
|
||
<p align="center"><font face="Verdana" size="1">7</font></p>
|
||
</td>
|
||
<td width="79" height="13">
|
||
<p align="center"><font face="Verdana" size="1">IFCLKSRC</font></p>
|
||
</td>
|
||
<td width="547" height="13"> <p align="left"><font face="Verdana" size="1">Set
|
||
to 1 to run the GPIF using the internal clock source</font></p>
|
||
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td width="38">
|
||
<p align="center"><font face="Verdana" size="1">6</font></p>
|
||
</td>
|
||
<td width="79">
|
||
<p align="center"><font face="Verdana" size="1">3048MHz</font></p>
|
||
</td>
|
||
<td width="547">
|
||
<p><font face="Verdana" size="1">Set to 1 to run the
|
||
internal clock source for the GPIF at 48MHz.</font></p>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td width="38">
|
||
<p align="center"><font face="Verdana" size="1">5</font></p>
|
||
</td>
|
||
<td width="79">
|
||
<p align="center"><font face="Verdana" size="1">IFCLKOE</font></p>
|
||
</td>
|
||
<td width="547">
|
||
<p><font face="Verdana" size="1">Set to 1 to turn on
|
||
the IFCLK output to drive the WCLK and RCLK inputs of
|
||
the external FIFO.</font></p>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td width="38">
|
||
<p align="center"><font face="Verdana" size="1">4</font></p>
|
||
</td>
|
||
<td width="79">
|
||
<p align="center"><font face="Verdana" size="1">IFCLPOL</font></p>
|
||
</td>
|
||
<td width="547">
|
||
<p><font face="Verdana" size="1">Set to 0.</font></p>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td width="38">
|
||
<p align="center"><font face="Verdana" size="1">3</font></p>
|
||
</td>
|
||
<td width="79">
|
||
<p align="center"><font face="Verdana" size="1">ASYNC</font></p>
|
||
</td>
|
||
<td width="547">
|
||
<p><font face="Verdana" size="1">Set to 0 to operate
|
||
the GPIF at the highest rate (sync mode).</font></p>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td width="38">
|
||
<p align="center"><font face="Verdana" size="1">2</font></p>
|
||
</td>
|
||
<td width="79">
|
||
<p align="center"><font face="Verdana" size="1">GSTATE</font></p>
|
||
</td>
|
||
<td width="547">
|
||
<p><font face="Verdana" size="1">Set to 1 to turn on
|
||
the debug outputs of the state machine. PE[2:0] displays
|
||
the states the GPIF engine cycles through during each
|
||
transaction (Note: PE[2:0] are only available on the
|
||
100- and 128-pin packages).</font></p>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td width="38">
|
||
<p align="center"><font face="Verdana" size="1">1</font></p>
|
||
</td>
|
||
<td width="79">
|
||
<p align="center"><font face="Verdana" size="1">IFCFG1</font></p>
|
||
</td>
|
||
<td width="547">
|
||
<p><font face="Verdana" size="1">Set to 1 to put the
|
||
FX2 part into GPIF mode (internal master).</font></p>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td width="38">
|
||
<p align="center"><font face="Verdana" size="1">0</font></p>
|
||
</td>
|
||
<td width="79">
|
||
<p align="center"><font face="Verdana" size="1">IFCFG0</font></p>
|
||
</td>
|
||
<td width="547">
|
||
<p><font face="Verdana" size="1">Set to 0 to put
|
||
the FX2 part into GPIF mode (internal master).</font></p>
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
<p><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">Table 4. IFCONFIG register bit settings for FIFO example<br>
|
||
<br>
|
||
</font></p>
|
||
|
||
</td>
|
||
</tr>
|
||
|
||
<tr valign="top">
|
||
<td colspan="1" align="left">
|
||
<ul>
|
||
|
||
<p>
|
||
<font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">The next thing TD_Init() does is it resets the external FIFO by pulsing PA2. This ensures that the external FIFO is at a
|
||
ground-zero state before commencing data operations. The following code does the trick:<br>
|
||
|
||
</font>
|
||
</ul>
|
||
|
||
</td>
|
||
</tr>
|
||
|
||
<tr valign="top">
|
||
<td colspan="1" align="left">
|
||
|
||
<p>
|
||
<blockquote>
|
||
<ul>
|
||
<font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000"><font color="#339933">// reset the external FIFO</font><br>
|
||
<br>
|
||
OEA |= <font color="#0000CC">0x04</font>; <font color="#339933">// turn on PA2 as output pin</font><br>
|
||
IOA |= <font color="#0000CC">0x04</font>; <font color="#339933">// pull PA2 high initially</font><br>
|
||
IOA &= <font color="#0000CC">0xFB</font>; <font color="#339933">// bring PA2 low</font><br>
|
||
<font color="#666666">EZUSB_Delay (<font color="#0000CC">1</font>)</font>; <font color="#339933">// keep PA2 low for ~1ms, more than enough time</font><br>
|
||
IOA |= <font color="#0000CC">0x04</font>; <font color="#339933">// bring PA2 high</font><br>
|
||
</font>
|
||
</ul>
|
||
|
||
</blockquote>
|
||
|
||
</td>
|
||
</tr>
|
||
|
||
<tr>
|
||
<td colspan="1" align="center" height="15">
|
||
<ul>
|
||
|
||
<p align="left">
|
||
<font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">A vendor command was also setup in the DR_VendorCmnd() function so that the user could reset the external FIFO at any time by
|
||
performing a vendor request of 0xB2 from the EZ-USB Control Panel. </font>
|
||
</ul>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td colspan="1" align="center" height="15">
|
||
|
||
<ul>
|
||
<p align="left"><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000"><B><a name="WritingHPIC"></a>Writing to the HPIC and HPIA registers</B><br>
|
||
</font>
|
||
</ul>
|
||
</td>
|
||
</tr>
|
||
<tr valign="top">
|
||
<td colspan="1" align="left">
|
||
<ul>
|
||
|
||
<p>
|
||
<font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">The firmware implements a 0xB6 IN vendor command and a 0xB7 IN vendor command to write to the HPIC and HPIA registers,
|
||
respectively. The following code writes to the HPIC register:</font>
|
||
<ul>
|
||
<p> <font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">case VX_B6: <font color="#339933">// write to HPIC register</font><br>
|
||
{<br>
|
||
<br>
|
||
EP0BCL = <font color="#0000CC">0</font>; <font color="#339933">// re-arm EP0</font><br>
|
||
<font color="#990000">while</font>(EP01STAT & bmEP0BSY); <font color="#339933">// wait until EP0 is available to be accessed by CPU</font><br>
|
||
<font color="#990000">while</font>(!HPI_RDY); <font color="#339933">// wait for HPI to complete internal portion of previous transfer</font><br>
|
||
IOA = bmHPIC; <font color="#339933">// select HPIC register</font><br>
|
||
GPIFWFSELECT = <font color="#0000CC">0xE4</font>; <font color="#339933">// point to waveforms that write first byte of HPI protocol</font><br>
|
||
GPIF_SingleByteWrite(EP0BUF[<font color="#0000CC">0</font>]); <font color="#339933">// write LSB of DSP address</font><br>
|
||
GPIFWFSELECT = <font color="#0000CC">0xA4</font>; <font color="#339933">// point to waveforms that write second byte of HPI protocol</font><br>
|
||
GPIF_SingleByteWrite(EP0BUF[<font color="#0000CC">1</font>]); <font color="#339933">// write MSB of DSP address</font><br>
|
||
<br>
|
||
<font color="#990000">break</font>;<br>
|
||
}</font></p>
|
||
</ul>
|
||
<p><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">The first thing the code does is it re-arms the EP0 buffer to accept the next packet from the host. It then waits until the EP0 buffer
|
||
is available for the CPU to access. Before addressing the HPIC register, the code checks to see if the HPI is ready to accept
|
||
another transfer. The HPIC register is then addressed by writing a 0 to both PA3 and PA2.<br>
|
||
<br>The technique of changing the waveform index in the GPIFWFSELECT register to point to different waveforms is useful for
|
||
handling protocols such as the HPI, where more than one waveform behavior is required to describe a complete read/write cycle.
|
||
The GPIFWFSELECT register is first configured to point to the SnglWr1 waveform which writes the first byte of the HPI protocol.
|
||
This is now the waveform that gets triggered when a GPIF single write access occurs. The first byte in EP0BUF is then written
|
||
out to the HPI. The GPIFWFSELECT register is then configured to point to the SnglWr2 waveform which writes the second byte
|
||
of the HPI protocol. This is now the waveform that gets triggered when a GPIF single write access occurs. The second byte in
|
||
EP0BUF is then written out to the HPI. Because the HPI protocol calls out that both first and second bytes in the HPI transfer
|
||
should be of equal value when writing to the HPIC register, the host should send down two bytes of equal value when performing
|
||
the vendor IN request of 0xB6.</font></p>
|
||
<p><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000"><br>The following code writes to the HPIA register:<br></font></p>
|
||
<blockquote>
|
||
<font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">case VX_B7: <font color="#339933">// write to HPIA register</font><br>
|
||
{<br>
|
||
<br>
|
||
EP0BCL = <font color="#0000CC">0</font>; <font color="#339933">// re-arm EP0</font><br>
|
||
<font color="#990000">while</font>(EP01STAT & bmEP0BSY); <font color="#339933">// wait until EP0 is available to be accessed by CPU</font><br>
|
||
<font color="#990000">while</font>(!HPI_RDY); <font color="#339933">// wait for HPI to complete internal portion of previous transfer</font><br>
|
||
IOA = bmHPIA; <font color="#339933">// select HPIA register</font><br>
|
||
GPIFWFSELECT = <font color="#0000CC">0xE4</font>; <font color="#339933">// point to waveforms that write first byte of HPI protocol</font><br>
|
||
GPIF_SingleByteWrite(EP0BUF[<font color="#0000CC">0</font>]); <font color="#339933">// write LSB of DSP address</font><br>
|
||
GPIFWFSELECT = <font color="#0000CC">0xA4</font>; <font color="#339933">// point to waveforms that write second byte of HPI protocol</font><br>
|
||
GPIF_SingleByteWrite(EP0BUF[<font color="#0000CC">1</font>]); <font color="#339933">// write MSB of DSP address</font><br>
|
||
<br>
|
||
<font color="#990000">break</font>;<br>
|
||
}<br></font>
|
||
</blockquote>
|
||
|
||
<p>
|
||
<font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">The first thing the code does is it re-arms the EP0 buffer to accept the next packet from the host. It then waits until the EP0 buffer
|
||
is available for the CPU to access. Before addressing the HPIA register, the code checks to see if the HPI is ready to accept
|
||
another transfer. The HPIA register is then addressed by writing a 1 to PA3 and a 0 to PA2.<br><br>The GPIFWFSELECT register is then configured to point to the SnglWr1 waveform which writes the first byte of the HPI protocol.
|
||
This is now the waveform that gets triggered when a GPIF single write access occurs. The first byte in EP0BUF is then written
|
||
out to the HPI. The GPIFWFSELECT register is then configured to point to the SnglWr2 waveform which writes the second byte
|
||
of the HPI protocol. This is now the waveform that gets triggered when a GPIF single write access occurs. The second byte in
|
||
EP0BUF is then written out to the HPI. When the host performs the vendor IN request of 0xB7, the first byte contains the LSB of
|
||
the DSP address, and the second byte contains the MSB of the DSP address.<br>
|
||
<font color="#339933"> </font></font>
|
||
</ul>
|
||
</td>
|
||
</tr>
|
||
|
||
<tr valign="top">
|
||
<td colspan="1" align="left">
|
||
|
||
<p>
|
||
|
||
<ul>
|
||
<font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000"><B><a name="HPIRdWr"></a>Performing Data Writes and Reads to and from the HPI</B></font>
|
||
</ul>
|
||
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td colspan="1" align="center" height="15">
|
||
<ul>
|
||
|
||
<p align="left">
|
||
<font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">The code in TD_Poll() handles USB OUT transfers (Data Writes to the HPI) and USB IN transfers (Data Reads from the HPI).<br>
|
||
<br>
|
||
Code that handles USB OUT Transfers</font>
|
||
<ul>
|
||
|
||
<p align="left">
|
||
<font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000"><font color="#990000">if</font> ( GPIFTRIG & <font color="#0000CC">0x80</font> )<font color="#339933"> // if GPIF interface IDLE</font><br>
|
||
{<br>
|
||
<font color="#990000">if</font> ( ! ( EP24FIFOFLGS & <font color="#0000CC">0x02</font> ) ) <font color="#339933">// if there's a packet in the peripheral domain for EP2</font><br>
|
||
{<br>
|
||
IOA = bmHPID_AUTO; <font color="#339933">// select HPID register with address auto-increment</font><br>
|
||
<font color="#990000">while</font>(!HPI_RDY); <font color="#339933">// wait for HPI to complete internal portion of previous transfer</font><br>
|
||
<br>
|
||
<font color="#666666">SYNCDELAY</font>;<br>
|
||
GPIFTCB1 = EP2FIFOBCH; <font color="#339933">// setup transaction count with number of bytes in the EP2 FIFO</font><br>
|
||
<font color="#666666">SYNCDELAY</font>;<br>
|
||
GPIFTCB0 = EP2FIFOBCL;<br>
|
||
<font color="#666666">SYNCDELAY</font>;<br>
|
||
GPIFTRIG = GPIF_EP2; <font color="#339933">// launch GPIF FIFO WRITE Transaction from EP2 FIFO</font><br>
|
||
<font color="#666666">SYNCDELAY</font>;<br>
|
||
<br>
|
||
<font color="#990000">while</font>( !( GPIFTRIG & <font color="#0000CC">0x80</font> ) ) <font color="#339933">// poll GPIFTRIG.7 GPIF Done bit</font><br>
|
||
{<br>
|
||
;<br>
|
||
}<br>
|
||
<br>
|
||
<font color="#666666">SYNCDELAY</font>;<br>
|
||
}<br>
|
||
}</font>
|
||
</ul>
|
||
|
||
<p align="left">
|
||
<font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">The first thing the OUT handling code does is it checks to see if the GPIF is IDLE. If so, it checks to see if there is at least a packet
|
||
in the peripheral domain for EP2. Since EP2 is placed into auto mode, the firmware does not need to check if the host sent a
|
||
USB packet. The USB packets are automatically committed to be used by the GPIF engine. Therefore, the firmware's job is to
|
||
check if at least one packet has been committed to the peripheral domain.<br>
|
||
<br>
|
||
The TC value is then simply setup with the number of bytes in the EP2 FIFO. This allows the user to handle packet sizes less
|
||
than 512 but greater than zero. The TC value is a 32-bit register field, but for this application only the lower 16-bit fields are used.<br>
|
||
<br>
|
||
A write to the GPIFTRIG register with the appropriate bits triggers the transaction from EP2OUT. The code then waits for the
|
||
transaction to complete before exiting out of the <B>if</B> nest.<br><br>Code that handles USB IN transfers</font>
|
||
<ul>
|
||
|
||
<p align="left">
|
||
<font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000"><font color="#990000">if</font>(in_enable) <font color="#339933">// if IN transfers are enabled,</font><br>
|
||
{<br>
|
||
<font color="#990000">if</font>(Tcount) <font color="#339933">// if Tcount is not zero</font><br>
|
||
{<br>
|
||
<font color="#990000">if</font>( GPIFTRIG & <font color="#0000CC">0x80</font> ) <font color="#339933">// if GPIF interface IDLE</font><br>
|
||
{<br>
|
||
<font color="#990000">if</font>( !( EP68FIFOFLGS & <font color="#0000CC">0x01</font> ) ) <font color="#339933">// if EP6 FIFO is not full</font><br>
|
||
{<br>
|
||
IOA = bmHPID_AUTO; <font color="#339933">// select HPID register with address auto-increment</font><br>
|
||
<font color="#990000">while</font>(!HPI_RDY); <font color="#339933">// wait for HPI to complete internal portion of previous transfer</font><br>
|
||
<br>
|
||
<font color="#666666">SYNCDELAY</font>;<br>
|
||
GPIFTCB1 = MSB(Tcount); <font color="#339933">// setup transaction count with Tcount value</font><br>
|
||
<font color="#666666">SYNCDELAY</font>;<br>
|
||
GPIFTCB0 = LSB(Tcount);<br>
|
||
<font color="#666666">SYNCDELAY</font>;<br>
|
||
GPIFTRIG = GPIFTRIGRD | GPIF_EP6; <font color="#339933">// launch GPIF FIFO READ Transaction to EP6IN</font><br>
|
||
<font color="#666666">SYNCDELAY</font>;<br>
|
||
<br>
|
||
<font color="#990000">while</font>( !( GPIFTRIG & <font color="#0000CC">0x80</font> ) ) <font color="#339933">// poll GPIFTRIG.7 GPIF Done bit</font><br>
|
||
{<br>
|
||
;<br>
|
||
}<br>
|
||
<br>
|
||
<font color="#666666">SYNCDELAY</font>;<br>
|
||
xFIFOBC_IN = ( ( EP6FIFOBCH << <font color="#0000CC">8</font> ) + EP6FIFOBCL ); <font color="#339933">// get EP6FIFOBCH/L value</font><br>
|
||
<br>
|
||
<font color="#990000">if</font>( xFIFOBC_IN < <font color="#0000CC">0x0200</font> ) <font color="#339933">// if pkt is short,</font><br>
|
||
{<br>
|
||
INPKTEND = <font color="#0000CC">0x06</font>; <font color="#339933">// force a commit to the host</font><br>
|
||
}<br>
|
||
Tcount = <font color="#0000CC">0</font>; <font color="#339933">// set Tcount to zero to cease reading from DSP HPI RAM</font><br>
|
||
}<br>
|
||
}<br>
|
||
}<br>
|
||
}</font>
|
||
</ul>
|
||
|
||
<p align="left">
|
||
<font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">If the in_enable flag is not set via vendor IN command 0xB3, the code will just sit there and not process the INs. If the in_enable
|
||
flag is set, and then if Tcount is not zero (read along for a further explanation of the Tcount variable), the code will fall through
|
||
and check if the GPIF interface is IDLE. It then determines if EP6 is not full, implying that it has room for at least one more data
|
||
packet.<br>
|
||
<br>
|
||
If EP6 has room for at least one more data packet, the TC value is setup with a user defined value of Tcount. The value of Tcount
|
||
is setup prior to the IN transfer and can be done so by executing the vendor OUT command 0xB5. For example, if the user wanted
|
||
to read 4KB worth of information from the HPI, the user would send a value of 0x1000 using the vendor OUT command 0xB5.
|
||
This requires that the user should have a priori knowledge of how much data is going to be read.<br>
|
||
<br>
|
||
A write to the GPIFTRIG register with the appropriate bits triggers the transaction to fill the EP6 FIFO. The code then waits for
|
||
the transaction to complete. Since EP6 is placed into auto mode, there is no need to explicitly write a byte count value to indicate
|
||
how many bytes to send to the host. FX2 uses the EP6AUTOINLENH/L register values set at enumeration time in the
|
||
DR_SetConfiguration() function for the auto commit size.<br>
|
||
<br>
|
||
However, to handle packets sizes less than 512 (the last packet of the transfer will typically be short), the code checks to see if
|
||
it needs to write to the INPKTEND register with a 0x06 to commit the short packet to the host. The Tcount variable is then set to
|
||
zero to prevent from entering the loop again. Now we see the relevance of the upper if statement that checks for Tcount. If the
|
||
statement was not present, the code would continously fill EP6IN as the host requests IN after IN. This complicates matters on
|
||
the host side becasue when the next transfer is started, <i>stray</i> buffers from the previous transfer would be retrieved by the host.
|
||
By checking if Tcount is greater than zero, the user would be forced to set the Tcount variable to the desired value to start another
|
||
transfer.<br>
|
||
</font>
|
||
</ul>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td colspan="1" align="center" height="15">
|
||
|
||
|
||
<ul>
|
||
<p align="left"><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000"><B><a name="INT0"></a>Handling INT0</B></font>
|
||
</ul>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td colspan="1" align="center" height="15">
|
||
|
||
<ul>
|
||
|
||
<p align="left">
|
||
<font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">The HINT/ output is connected to the INT0/ interrupt on the FX2. This allows the 5416 to perform software handshaking with the
|
||
FX2 when necessary. The INT0/ interrupt is handled via the following ISR:<br></font>
|
||
<ul>
|
||
|
||
<p align="left">
|
||
<font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000"><font color="#990000">void</font> int0_isr (<font color="#990000">void</font>) <font color="#339933">// interrupt 0</font><br>
|
||
{<br>
|
||
hpi_int = TRUE; <font color="#339933">// HPI interrupted the FX2</font><br>
|
||
EX0 = <font color="#0000CC">0</font>; <font color="#339933">// disable INT0/ interrupt, let foreground re-enable it</font><br>
|
||
}<br>
|
||
</font>
|
||
</ul>
|
||
|
||
<p align="left">
|
||
<font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">The ISR sets a global flag hpi_int which is monitored by TD_Poll(). The code in TD_Poll then clears the hpi_int flag and turns on
|
||
LED1 on the FX2 development board:<br>
|
||
</font>
|
||
<ul>
|
||
|
||
<p align="left">
|
||
<font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000"><font color="#990000">if</font> (hpi_int)<br>
|
||
{<br>
|
||
hpi_int = FALSE; <font color="#339933">// clear HPI interrupt flag</font><br>
|
||
EX0 = <font color="#0000CC">1</font>; <font color="#339933">// enable INT0 interrupt again</font><br>
|
||
LED_On (bmBIT1); <font color="#339933">/ turn on LED1 to alert user HPI interrupt occurred</font><br>
|
||
}<br>
|
||
</font>
|
||
</ul>
|
||
|
||
<p align="left">
|
||
<font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">A vendor IN command of 0xB2 is provided so that the user can turn off LED1.<br>
|
||
<br> </font>
|
||
</ul>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td colspan="1" align="center" height="15">
|
||
|
||
<p align="left"><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000"><B><a name="Running"></a>Running the DSP
|
||
example<br> </B></font> </td>
|
||
</tr>
|
||
<tr>
|
||
<td colspan="1" align="center" height="15">
|
||
|
||
|
||
<p align="left">
|
||
<font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">Now that the user has a good idea how this DSP example works, we can now attempt to read and write to the HPI and later on bootload the DSP code.<br><br>Step 1: Download the firmware using the EZ-USB Control Panel<br></font>
|
||
<ul>
|
||
<p align="left"><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">a)
|
||
Unzip the "FX2_to_TI5416_HPI GPIF FIFO Transactions Auto Mode.zip" package in the C:\Cypress\USB\Examples\FX2 directory.<br></font></p>
|
||
<p align="left"><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">b)
|
||
Plug in the 5416 DSK board and launch the Code Composer Studio for the 5416.<br></font></p>
|
||
<p align="left"><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">c)
|
||
After the user plugs-in the FX2 board, launch the EZ-USB Control Panel and ensure that the selected target is FX2.<br></font></p>
|
||
<p align="left"><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">d)
|
||
Then, press the <i>Download</i> button and select the FX2_to_TI5416_HPI.hex file. The FX2 board renumerates as a Cypress EZ-USB Sample Device and LED0 should come up flashing.</font></p>
|
||
<p align="left"><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">e)
|
||
Perform a <i>Get Pipes</i> and <i>Get Dev</i> to verify one more time that the firmware is up and running. The user should then see the following screen shown below:<br></font></p>
|
||
<p align="left"><A onClick="na_change_img_src('image2', 'document', 'images/dsp-cp1.gif', true);"><img src="images/dsp-cp1.gif" width="488" height="400" align="center" border="0" name="image2"></A> </ul>
|
||
|
||
<p><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000"><br> </font></p>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td colspan="1" align="center" height="15">
|
||
|
||
<p align="left">
|
||
<font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000"><a name="Step2"></a>Step 2: Perform a write to the HPI<br></font>
|
||
<ul>
|
||
<p align="left"><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">a)
|
||
Launch Code Composer Studio and pull up the <i>Memory</i> window at 0x7000. This will allow the user to monitor if the writes occurred correctly.<br></font></p>
|
||
<p align="left"><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">b)
|
||
Perform a vendor OUT command of 0xB6 to write to the HPIC register using data values 0x01 0x01. This sets the BOB to
|
||
1 in the HPIC register so that the first byte of future HPI transfers is the LSB and the second byte is the MSB (as organized in DSP memory)<br></font></p>
|
||
<p align="left"><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">c)
|
||
Perform a vendor OUT command of 0xB7 to write to the HPIA register with the address of 0x7000. Notice the ordering of the data in the hex bytes field since the BOB bit has been set to 1.<br></font></p>
|
||
<p align="left"><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">d)
|
||
Perform another vendor OUT command of 0xB6 to write to the HPIC register using data values 0x11 0x11. This keeps the
|
||
BOB bit set at 1 and sets the XPHIA bit. Setting the XPHIA bit does two things: 1) it allows the address to auto-increment for
|
||
consecutive data accesses to HPI and 2) the next write to the HPIA register contains the extended address value.<br></font></p>
|
||
<p align="left"><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">e)
|
||
Perform another vendor OUT command of 0xB7 to write the extended address value into the HPIA register. The value is 0x00 0x00 since the address 0x7000 lies within the first page of DSP memory.<br></font></p>
|
||
<p align="left"><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">f)
|
||
Select Endpoint 2 OUT as the <i>Pipe</i>, press the <i>FileTrans ..</i> buttion and select the 512_count.hex file. Click on <i>Open</i> and
|
||
this action will send out 512 bytes of ramp data to the HPI.<br></font></p>
|
||
</ul>
|
||
<p align="left"><A onClick="na_change_img_src('image1', 'document', 'images/dsp-cp2.gif', true);"><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000"><img src="images/dsp-cp2.gif" width="543" height="361" align="center" border="0" name="image1"></font></A> <ul>
|
||
|
||
<p align="left">
|
||
<font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000"><br>Since the auto-increment mode is used to write data to the HPI, the first data value will appear at 0x7001 since the HPI pre-increments the address
|
||
prior to the data write. If the user wanted the first data value to appear at 0x7000, the address to write to the HPIA register would have been 0x6FFF.<br>
|
||
<br>
|
||
The user could have also used the <i>Bulk Trans</i> button to send a specific data pattern to the HPI.<br>
|
||
<br>
|
||
The Memory window of Code Composer Studio indicates the HPI write was successful.<br>
|
||
</font> </ul>
|
||
|
||
|
||
|
||
<p align="left"><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000"><img name="law" src="images/mem7000.gif" width="525" height="300" align="center" border="0"></font> <br> </td>
|
||
</tr>
|
||
<tr>
|
||
<td colspan="1" align="center" height="15">
|
||
|
||
<p align="left">
|
||
<font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000"><a name="Step3"></a>Step 3: Perform a Read from the HPI</font>
|
||
<ul>
|
||
<p align="left"><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">To read from a specific address in the DSP, the user should perform steps a. through e. as listed in Step 2. For HPI auto-increment
|
||
reads, the DSP post-increments the address for a data read, so the user can exactly specify the address to read from. In this
|
||
instance, we will read back the data values previously written in step 2. We will read 768 bytes to illustrate that the FX2 firmware
|
||
can handle short packets (since 768 is not an even divisor of 512).<br></font></p>
|
||
<p align="left"><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">a)
|
||
Perform a 0xB5 vendor OUT command to set the Tcount variable to 768 (0x0300). This sets up the GPIF to read 768 bytes from the HPI.<br></font></p>
|
||
<p align="left"><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">b)
|
||
Pend an IN request for 768 bytes on Endpoint 6 IN.<br></font></p>
|
||
<p align="left"><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">c)
|
||
Perform a 0xB3 vendor IN command to set the in_enable flag to TRUE. 768 bytes worth of data should now be displayed
|
||
on the EZ-USB Control Panel window. Note that the data values are the same as the ones previously written by the HPI
|
||
write, thus proving that the read was a success.<br></font></p>
|
||
</ul>
|
||
|
||
<p align="left"><A onClick="na_change_img_src('image3', 'document', 'images/dsp-cp3.gif', true);"><img src="images/dsp-cp3.gif" width="544" height="360" border="0" name="image3"></A></p>
|
||
<p align="center"> </p>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td colspan="1" align="center" height="15">
|
||
|
||
|
||
<p align="left">
|
||
<font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000"><a name="Step4"></a>Step 4: Bootloading the DSP code<br></font>
|
||
<ul>
|
||
<p align="left">
|
||
<font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">A host processor can download the DSP code via the HPI and <i>bootload</i> it by writing the entry point of the program to location
|
||
0x7E and 0x7F in DSP data memory. This is a common method used to bootload a TI DSP. To force the 5416 to use the HPI as
|
||
the bootload method, the HINT/ and INT2/ pins are tied together. The host processor just needs to then download the code, write
|
||
the entry point, and the DSP program starts running. For simplicity sake, this example chose to use the LED code supplied in the
|
||
5416 DSK software. Once the bootload is complete, the user LED0 on the DSK board starts flashing.<br>
|
||
<br>
|
||
The bootloading techniques used in this example are very similar to those explained in the TI appnote SPRA382. Code Composer
|
||
Studio generates a .out executable file that follows the Common Object File Format (COFF). This .out file cannot be simply
|
||
downloaded to the DSP. The program and data sections need to be extracted by running a COFF Hex Extraction Utility on the
|
||
.out file. This utility is available with the SPRA382 appnote. After typing in the command <i>coff_both -out led.out</i>, the utility creates
|
||
a hex listing that is called led.out.c.<br>
|
||
<br>
|
||
A PC application created in MS VC++ 6.0 called HPIMr (short for HPI Manager) reads in this hex listing, determines the start
|
||
address of each section, and writes each section of code/data to the FX2's Endpoint 2 OUT. Prior to writing each block of
|
||
code/data, the sequence of 0xB6 and 0xB7 vendor OUT commands are performed to write to the HPIC/HPIA registers (similar
|
||
to Step 2). The source code for the HPIMr utility is provided if the user is interested in seeing how this is done. This utility can
|
||
also serve as another host application example.<br>
|
||
<br>
|
||
These are the steps the user should follow to download the LED example:<br></font></p>
|
||
<p align="left"><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">a)
|
||
Plug in the 5416 DSK board, plug in the FX2 development board.<br></font></p>
|
||
<p align="left"><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">b)
|
||
Download the FX2_to_TI5416_HPI.hex firmware.<br></font></p>
|
||
<p align="left"><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">c)
|
||
Run the HPIMr.exe utility. The user should see the following screen if an FX2 development board is plugged in.<br></font></p>
|
||
<ul>
|
||
<p align="left"><img name="law" src="images/hpimr1.gif" width="326" height="202" align="center" border="0">
|
||
</ul>
|
||
<p align="left"> </p>
|
||
<p align="left"><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">d)
|
||
Next, click on the <i>Send Program to HPI</i> button and select the led.out.c file. Click on <i>Open</i>.<br></font></p>
|
||
|
||
<ul>
|
||
<p align="left"><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000"><img name="law" src="images/hpimr2.gif" width="428" height="266" align="center" border="0"><br>
|
||
<br>
|
||
</font>
|
||
</ul>
|
||
<p align="left"><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">The user should should now see the user LED0 flashing on the 5416 DSK board.<br></font></p>
|
||
|
||
<ul>
|
||
<p align="left"><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000"><img name="law" src="images/hpimr3.gif" width="326" height="202" align="center" border="0"><br> </font>
|
||
</ul>
|
||
</ul>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td colspan="1" align="center" height="15">
|
||
<p align="left"><font face="Verdana" size="1"><b><a name="Traces"></a>Logic
|
||
Analyzer Traces<br></b><br>These are the traces the user should
|
||
see on the logic analyzer as the DSP example runs.
|
||
The traces were captured using an HP1660C logic analyzer.<br><br><b> </b></font></p>
|
||
<p align="left"><font face="Verdana,Arial" size="1" color="black"><b><a name="WriteHPIC1"></a>Writing to HPIC</b></font><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">:
|
||
Zoomed out view<br>
|
||
<br>This trace shows what the user should see when a 0xB6 vendor OUT command is performed to write to the HPIC register
|
||
(HCNTL=00). The first byte of the HPI transfer is followed by IDLE time, where the FX2 firmware is switching to the GPIF single
|
||
write waveform that writes the second byte of the HPI transfer. A similar waveform can be observed when a 0xB7 vendor OUT
|
||
command is performed to write to the HPIA register.<br>
|
||
<br><br></font><img src="images/law1.gif" width="543" height="362" align="center" border="0" ismap usemap="#cancel_map">
|
||
<p> </p>
|
||
<p align="left"><font face="Verdana,Arial" size="1" color="black"><b><a name="WriteHPIC2"></a>Writing to HPIC</b></font><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">: Close-up view of 1st byte of HPI transfer<br><br><br>Here we see a close-up view of the 1st byte of a HPI write to the HPIC register. A write operation is signified by HR/W/ being
|
||
driven low. HBIL is also driven low to signify that this is the 1st byte of the HPI transfer. The timing shown here adheres to the
|
||
HPI8 Mode Timing Requirements in the 5416 datasheet. A similar waveform can be observed when a 0xB7 vendor OUT
|
||
command is performed to write to the HPIA register.<br>
|
||
<br><br></font><img src="images/law2.gif" width="543" height="362" align="center" border="0" ismap usemap="#ImageMap1"><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000"> <br><br> </font> <p align="left"><font face="Verdana,Arial" size="1" color="black"><b><a name="WriteHPIC3"></a>Writing to HPIC</b></font><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">: Close-up view of 2nd byte of HPI transfer<br>
|
||
<br><br>Here we see a close-up view of the 2nd byte of a HPI write to the HPIC register. A write operation is signified by HR/W/ being
|
||
driven low. HBIL is now driven high to signify that this is the 2nd byte of the HPI transfer. The timing shown here adheres to the
|
||
HPI8 Mode Timing Requirements in the 5416 datasheet. A similar waveform can be observed when a 0xB7 vendor OUT
|
||
command is performed to write to the HPIA register.<br>
|
||
<br><br></font><img src="images/law3.gif" width="544" height="362" align="center" border="0" ismap usemap="#ImageMap2"><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000"> <br><br> </font> <p align="left"><font face="Verdana,Arial" size="1" color="black"><b><a name="FIFOWrHPI1"></a>FIFO Write to HPI</b></font><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">: Zoomed out view<br>
|
||
<br><br>This is a snapshot of the activity that goes on when the FX2 performs a burst write to the HPI using GPIF FIFO Write transactions.
|
||
A similar waveform can be observed when the FX2 performs a burst read from the HPI using GPIF FIFO Read transactions.<br><br></font><img src="images/law4.gif" width="542" height="361" align="center" border="0" ismap usemap="#ImageMap3"><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000"> <br><br> </font> <p align="left"><font face="Verdana,Arial" size="1" color="black"><b><a name="FIFOWrHPI2"></a>FIFO Write to HPI</b></font><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">: Close-up view<br><br><br>Here we see a close-up view of a write to the HPI using GPIF FIFO Write transactions. S0-S5 marks the duration of a complete
|
||
HPI write access. Since it is a write, the HR/W/ signal is driven low for the duration of the transfer. In S0-S1, the HBIL signal is
|
||
driven low to transfer the first byte, and in S2-S3 the HBIL signal is driven high to transfer the second byte. The timing here
|
||
conforms to the HPI8 Mode Timing Requirements in the 5416 datasheet.<br>
|
||
<br>
|
||
Notice that the HRDY/ signal goes low after the second byte is transferred. The next HPI write does not start until the HRDY/ is
|
||
high again (indicating that the HPI is ready for the next write). S4 and S5 allow enough time for the HRDY/ signal to become high
|
||
again. Thus it was not necessary to check for HRDY/ in the GPIF waveform logic before starting the next HPI write sequence.
|
||
S5 is the decision point state that uses the GPIF transaction count expiration flag (RDY5) to determine whether or not the data
|
||
burst should continue.<br>
|
||
<br><br></font><img src="images/law5.gif" width="544" height="363" align="center" border="0" ismap usemap="#ImageMap4"><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000"> <br><br> </font> <p align="left"><font face="Verdana,Arial" size="1" color="black"><b><a name="FIFORdHPI"></a>FIFO Read from HPI</b></font><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">: Close-up view<br>
|
||
<br><br>Here we see a close-up view of a read from the HPI using GPIF FIFO Read transactions. S0-S5 marks the duration of a complete
|
||
HPI read access. Since it is a read, the HR/W/ signal is driven high for the duration of the transfer. In S0-S1, the HBIL signal is
|
||
driven low to transfer the first byte, and in S2-S3 the HBIL signal is driven high to transfer the second byte. The timing here
|
||
conforms to the HPI8 Mode Timing Requirements in the 5416 datasheet.<br>
|
||
<br>
|
||
Notice that the HRDY/ signal goes low after the second byte is transferred. The next HPI read does not start until the HRDY/ is
|
||
high again (indicating that the HPI is ready for the next read). S4 and S5 allow enough time for the HRDY/ signal to become high
|
||
again. Thus, it was not necessary to check for HRDY/ in the GPIF waveform logic before starting the next HPI read sequence.
|
||
S5 is the decision point state that uses the GPIF transaction count expiration flag (RDY5) to determine whether or not the data
|
||
burst should continue.<br>
|
||
<br><br></font><img src="images/law6.gif" width="544" height="362" align="center" border="0" ismap usemap="#ImageMap5"><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000"> <br><br> </font> <p align="left"><font face="Verdana,Arial" size="1" color="black"><b><a name="DnLoadDSP"></a>Downloading DSP code<br></b></font><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">
|
||
<br>This is a snapshot of the activity that goes on when the FX2 downloads the DSP code to the 5416 DSK board.<br>
|
||
<br><br></font><img src="images/law7.gif" width="546" height="364" align="center" border="0" ismap usemap="#ImageMap6"><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000"> <br></font>
|
||
<p align="left"> </p>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td colspan="1" align="center" height="15">
|
||
|
||
<p align="left">
|
||
<font face="Verdana,Arial" size="1" color="black"><b><a name="Summary"></a>Summary</b></font><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000"><br></font>
|
||
<p align="left"><font face="verdana, arial, helvetica, sans-serif" size="1" color="#000000">This design example of an FX2 GPIF interface to a TI 5416 DSP's HPI has given the user another concrete example of how the
|
||
FX2 GPIF can be used in a practical application. This DSP example builds upon the external FIFO example, and extends the
|
||
user's understanding of how to create GPIF waveform descriptors and program the GPIF to perform reads and writes over the
|
||
physical interface. Because the HPI protocol is significantly more complex than that of an external FIFO's, the user can appreciate
|
||
what it takes to create a full featured GPIF application, and apply the techniques presented here to solve applications that have
|
||
slave devices with more sophisticated protocols.<br>
|
||
</font></p>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td colspan="1" align="center" height="15">
|
||
<p> </p>
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
|
||
<map name="cancel_map">
|
||
<area shape="rect" coords="391, 4, 447, 26" onClick="parent.frames[0].location='../cDsp80.htm'; parent.frames[1].location='../nDsp80.htm';">
|
||
</map><map name="ImageMap1">
|
||
<area shape="rect" coords="390, 4, 447, 26" onClick="parent.frames[0].location='../cDsp80.htm'; parent.frames[1].location='../nDsp80.htm';">
|
||
</map><map name="ImageMap2">
|
||
<area shape="rect" coords="391, 4, 448, 26" onClick="parent.frames[0].location='../cDsp80.htm'; parent.frames[1].location='../nDsp80.htm';">
|
||
</map><map name="ImageMap3">
|
||
<area shape="rect" coords="390, 4, 446, 26" onClick="parent.frames[0].location='../cDsp80.htm'; parent.frames[1].location='../nDsp80.htm';">
|
||
</map><map name="ImageMap4">
|
||
<area shape="rect" coords="391, 4, 448, 26" onClick="parent.frames[0].location='../cDsp80.htm'; parent.frames[1].location='../nDsp80.htm';">
|
||
</map><map name="ImageMap5">
|
||
<area shape="rect" coords="391, 4, 448, 26" onClick="parent.frames[0].location='../cDsp80.htm'; parent.frames[1].location='../nDsp80.htm';">
|
||
</map><map name="ImageMap6">
|
||
<area shape="rect" coords="392, 4, 449, 27" onClick="parent.frames[0].location='../cDsp80.htm'; parent.frames[1].location='../nDsp80.htm';">
|
||
</map>
|
||
</body>
|
||
</html>
|