Compiled Help Main Page

Handel-C and RC1000PP Help

Handel-C Help Files

RC1000PP Help Files

Disclaimer

The contents here are an abstract of the Handel-C,
Version 2.1 language reference and the RC1000PP documentation.

All rights belongs to Embedded Solutions Ltd.

Handel-C, copyright Embedded Solutions Ltd.

Help file compiled by Seng Shay Ping
16/10/99 Version 2.1a


Handel-C Help

The on-line Handel-C language guide does not contain the full Handel-C documentation. The complete documentation, entitled langref.pdf, can be found with the software distribution, in the /docs directory.

Declarations

arrays,
bin,
constants, channels,
dec,
oct,
ram/rom,
variables

Macros

constant macro expr,
macro procedures,
parameterised macro expr,
select, shared expr

Operators

arithmetic,
bit manupulation,
conditonal, constant expressions,
logical operators,
operator summary/precedence,
relational operators,
type casting

Statements

assignments,
break,
delay,
for loop,
if...else,
par, prialt,
sequential and parallel statements, switch,
while loop

Targeting Hardware

bidirectional transfers,
bus_in, bus_latch_in, bus_clock_in, bus_out,
bus_ts, bus_ts_latch_in,
bus_ts_clock_in,
interface,
offchip interfaces,
reading from external pins,
targetting hardware,
targetting specific devices,
writing to external pins

The contents here are an abstract of the Handel-C, Version 2.1 language reference.
All rights belongs to Embedded Solutions Ltd.
Please read the disclaimer.

Handel-C, copyright Embedded Solutions Ltd.

Help file compiled by Seng Shay Ping
3/11/99 Version 2.1a


Declarations

Arrays

It is possible to declare arrays of variables in the same way that arrays are declared in conventional C. For example:

int 6 x[7];
unsigned int 6 x[4][5][6];

When accessing an array, the index must be a compile time constant. If you require random access to an array of values, consider using a ram or rom as described below.

See also: RAMS and ROMS

Constants

Constants may be used within expressions where required. Decimal constants are written as the number alone. Hexadecimal constants must be prefixed with 0x or 0X, octal constants with 0 (a zero) and binary constants with 0b or 0B. For example:

w = 1234;       /* Decimal */
x = 0x1234;     /* Hexadecimal */
y = 01234;      /* Octal */
z = 0b00100110; /* Binary */

Channels

Handel-C provides channels for communicating between parallel branches of code. One branch writes to a channel and a second branch reads from it. The communication only occurs when both tasks are ready, then one item of data is transferred between the two branches.

chan int 7 x;     // Channel width 7bits called x
chan int 3 y[4];  // Array of channels
chanin int 3 in;  // input channel for simulation
chanout int 3 out;// output channel for simulation

in ? v;           // input from channel in to variable v
y[3] ! 2;         // output 2 to channel y[3]

As with arrays, indexes to channel arrays must be compile time constants.

See also: prialt

RAMs and ROMs

RAMs and ROMs may be built from the logic provided in the FPGA using the ram and rom keywords. This example constructs a RAM consisting of 43 entries each of which is 6 bits wide and a ROM consisting of 4 entries each of which is 16 bits wide. The ROM is initialised with the constants given in the following list in the same way as an array isinitialised in C. For example:

ram int 6 a[43];
rom int 16 b[4] = { 23, 46, 69, 92 };

x = b[3]; //x is given the value 92

Note that RAMs differ from arrays in that an array is equivalent to declaring a number of variables. Each entry in an array may be used exactly like an individual variable with as many reads and writes in a clock cycle as required. RAMs, however, are normally more efficient to implement in terms of hardware resources than arrays and also allow a non-constant index. Therefore, you should use an array when you wish to access the elements in parallel and you should use a RAM when you wish to have random access to the elements.

See also: arrays

Variables

There is only one fundamental type for variables: int. In addition, the int type may be qualified with the unsigned keyword to indicate that the variable only contains positive integers. For example:

int width wire_name;
int 5 x;
unsigned int 13 y;
signed int 17 x, y, z;
int 15 a = 1234;
int undefined b;
short c;
long d;
char e;
char | 8 bits
short | 16 bits
long | 32 bits
undefined | undeclared width, will be infered

See also: Type casting


Macros

Constant Macro Expressions

The simplest form of the macro is an expression. For example:

macro expr DATA_WIDTH = 15;
int DATA_WIDTH x;

This form of the macro is similar to the #define macro. Whenever DATA_WIDTH appears in the program, the constant 15 is inserted in its place. More generally, real expressions can be used. For example:

macro expr sum = (x + y) @ (y + z);
v = sum;
w = sum;

Macro Procedures

Macros may be used to replace statements to avoid tedious repetition. Handel-C provides simple macro constructs to expand single statements into complex blocks of code. The general syntax of macro procedures is:

macro proc Name(Params) Statement

For example:

macro proc output(x, y)
{
out ! x; out ! y;
}

output(a + b, c * d);
output(a + b, c * d);

Parametrised Macro Expressions

Handel-C also allows macros with parameters. For example:

macro expr add3(x) = x + 3;
y = add3(z);

This is equivalent to the following code:

y = z + 3;

Select Operator

Handel-C provides a select(...)operator which is used to mean ‘select at compile time’. Its general usage is:

select(Expression, Expression if True, Expression if False)

The first expression must be a compile time constant. If the first expression evaluates to true then the Handel-C compiler replaces the whole expression with the second expression. If the first expression evaluates to false then the Handel-C compiler replaces it with the third expression.

A more useful example can be seen when macros are combined with this feature. For example:

macro expr adjust(x, n) =
     select(width(x) < n, (0 @ x), (x <- n));

unsigned 4 a;
unsigned 5 b;
unsigned 6 c;
b = adjust(a, width(b));
b = adjust(c, width(b));

This example is for a macro that equalises widths of variables in an assignment.

Shared Expressions

The shared expression allows hardware to be shared between different parts of the program to decrease hardware usage. The shared expression has the same format as a macro expression but does not allow recursion. An example program where shared expressions are extremely useful is:

shared expr mult(x, y) = x * y;
a = mult(b, c);
d = mult(e, f);
g = mult(h, i);

In this example, only one multiplier is built and it is used on every clock cycle. This is more efficient use of hardware.


Operators

Arithmetic operators

Operator | Meaning
+ | Addition
- | Subtraction
* | Multiplication

All operators return results of the same width as their operands. Thus, all overflow bits are lost. To obtain carry out information extend the input values. For example:

unsigned 4 x = 4;
unsigned 4 y = 8;
unsigned 5 z;
unsigned 4 sum;
unsigned 1 carry;

z = (0 @ x)+(0 @ y); //Extend the width to get
sum = z <- 4;      //carry out information
carry = z[4];

Precedence of operators is as expected from conventional C.

See also: Precedence summary

Bit manipulation

Operator | Meaning
<< | Shift left
>> | Shift right
<- | Take LSBs
\\ | Drop LSBs
@ | Concatenate bits
[ ] | Bit selection
width(expression) | Width of expression

unsigned int 8 x = 0b11110000;
int 4 z;

x = x >>1;           //
          x = 0b01111000
z = x <-4;           //
          z = 0b0000
z = x \\4;           //
          z = 0b1111
y = x[7:4] @ x[3:0]; // y = 0b00001111
z = width(x);        // z = 8

Arguments for >>, <<, <-, \\, [ ] must be compile time constants.

See also: Precedence summary

Conditional Operator

Handel-C provides the conditional expression construct familiar from conventional C. Its format is:

Expression ? Expression : Expression

The first expression is evaluated and if true the whole expression evaluates to the second expression. If the first expression is false, the whole expression evaluates to the third expression. For example:

x = (y > z) ? y : z;

See also: if...else , switch, select, Precedence summary

Compile Time Constant Expressions

In addition to all the operators listed in the previous sections, Handel-C provides two extra operators for expressions consisting only of compile time constants. These are:

Operator | Meaning
/ | Division
% | Modulo arithmetic

See also: Precedence summary

Logical Operators

Operator | Meaning
&& | Logical AND
|| | Logical OR
! | Logical NOT
& | Bitwise AND
| | Bitwise OR
^ | Bitwise XOR
~ | Bitwise NOT

See also: Precedence summary

Operator Summary/Precedence

The following table lists all operators in the Handel-C Language. Entries at the top have the highest precedence and entries at the bottom have the lowest precedence. Entries within the same group have the same precedence.

Operator | Meaning
array[constant] expression[constant] expression[constant:constant] RAM[expression] | Array subscripting Bit Selection Bit range extraction RAM/ROM subscript
! expression ~expression | Logical NOT Bitwise NOT
-expression | Unary Minus
(type) expression | Type casting
expression <- constant expression \\ constant | Take LSBs DROP LSBs
expression * expression constant / constant constant % constant | Mutiplication Division Molulo arithmetic
expression + expression expression - expression | Addition Subtraction
expression << constant expression >> constant | Shift left Shift right
expression @ expression | Concatenation
expression < expression expression > expression expression <= expression expression >= expression | Less than Greater than Less than or equal Greater then or equal
expression == expression expression != expression | Equal Not Equal
expression & expression | Bitwise AND
expression ^ expression | Bitwise XOR
expression | expression | Bitwise OR
expression && expression | Logical AND
expression || expression | Logical OR
expression ? expression : expression | Conditional Selection
width(expression) | Width of expression
select(constant, expression, expression) | Compile-time selection

Relational Operators

Operator | Meaning
== | Equal
!= | Not Equal
< | Less Than
> | Greater Than
<= | Less Than or Equal
>= | Greater Than or Equal

See also: Precedence summary

Type Casting

Type casting in Handel-C is done in the same way as in conventional C code. Before variables of differing types are assigned, they have to casted to compatible types.

However, casting cannot be used to change the width of values. Inorder to change the width of the variable, the compiler must be told how to pad the variable. It can then be casted to a different type.

int 4 x;
unsigned int 4 y;
int 8 z;

x = y; // Illegal
x = (int 4) y;

z = (int 8) x; // Illegal
z = (int 8) (1@x); // x is extended to 8 bits, with 1 in the 4 MSB
z = (int 8) (x@0); // x is extended to 8 bits, with 0 in the 4 LSB


Statements

Assignments

Handel-C also provides a number of short cut assignment statements. Note that these cannot be used in expressions as they can in conventional C but only in stand alone statements.

Statement
Expansion
var++;
   var = var+1;
++var;
   var = var+1;
var--;
   var=var-1;
--var;
   var=var-1;
var += expr
   var = var + expr
var -= expr
   var = var - expr
var *= expr
   var = var * expr
var <<= const
   var = var << const
var >>= const
   var = var >> const
var &= expr
   var = var & expr
var |= expr
   var = var | expr
var ^= expr
   var = var ^ expr

See also: Arithmetic, Relational, Logical operators

break

Handel-C provides the normal C break statement both for terminating loops and separation of case branches in switch and prialt statements. When used within a while, do...while or for loop, the loop is terminated and execution continues from the statement following the loop. For example:

for (x=0; x<32; x++)
{
if (a[x]==0) break;
b[x]=a[x];
}
// Execution continues here

See also: for, prialt, switch, while

delay

Handel-C provides a delay statement not found in conventional C which does nothing but takes one clock cycle to do it. This may be useful to avoid resource conflicts (for example to prevent two accesses to one RAM in a single clock cycle) or to adjust execution timing.

if (x < 10)
{
   x++;
}
else
{
   delay;
}

for loops

Handel-C provides for loops similar to those in conventional C.
Each of the initialisation, test and iteration statements are optional and may be omitted if not required. As with all other Handel-C constructs, Statement may be replaced with a block of statements. For example:

for (Initialisation ; Test ; Iteration)
Statement

for ( ; x>y ; x++ )
{ a = b; c = d; }

See also: break, while

if else statements

Handel-C provides the standard C conditional execution construct as follows:

if (Expression)
{Statement}
else
{Statement}

As in conventional C, the else portion may be omitted if not required. For example:

if (x == 1) x = x + 1;

See also: Conditional operator, Select

prialt statement

Handel-C provides a prialt statement not found in conventional C for selective channel communication.

prialt {
case CommsStatement:
  Statement
  break;
......
default:
  Statement
  break;
}

The prialt statement can be used to select between communication on a number of channels depending on the readiness of the other end of the channel communication. CommsStatement must be one of the following forms:

Channel ? Variable   //read to variable
Channel ! Expression //write to variable

The first communication statement in the list of cases which becomes ready to transfer data will execute. The statements up to the next break statement will then be executed.

In a prialt statement with no default case, execution will halt until one of the channels is ready to communicate.
In a prialt statement with a default case, if none of the channels is ready to communicate immediately then the default branch statements will execute and the prialt statement will terminate.

The prialt construct does not allow the same channel to be listed twice in its cases and fall through of cases is prohibited. This means that each case must be paired with its own break statement.

See also: break

Sequential and Parallel Statements

The following example executes three assignments sequentially:

x = 1;
y = 2;
z = 3;

In contrast, the following example executes all three assignments in parallel and in the same clock cycle:

par {
  x = 1;
  y = 2;
  z = 3;
}

In the diagram below, statements in the same colour will execute concurrently.
So for example, x = 1 and the second par{}
    block will execute concurrenty;
a = 1 and b = 1 will execute sequentially.
    However, y = 1, z = 1,
    and a = 1, will execute concurrently.

switch statement

Handel-C provides switch statements similar to those in conventional C.

switch (Expression)
{
case Constant:
  Statement
  break;
case 10:
  a = b;
case 11:
  c = d;
  break;
case 12:
  e = f;
  break;
......
default:
  Statement
  break;
}

Values following case and default keywords must be compile time constants.

The switch expression is evaluated and checked against each of the case compile time constants. The statement guarded by the matching constant is executed until a break statement is encountered.

If no matches are found, the default statement is executed, but if no default option is provided, no statements are executed. Each of the Statement lines above may be replaced with a block of statements by enclosing the block in {...} brackets.

As with conventional C, it is possible to make execution drop through case branches by omitting a break statement.

Here, if x is 10, b is assigned to a and d is assigned to c, if x is 11, d is assigned to c and if x is 12, f is assigned to e.

See also: break

while loops

Handel-C provides while loops exactly as in conventional C:

while (Expression) Statement

The contents of the while loop may be executed zero or more times depending on the value of Expression. While Expression is true then Statement is executed repeatedly. Again, Statement may be replaced with a block of statements. For example:

x = 0;
while (x != 45)
{
y = y + 5;
x = x + 1;
}

// Or to make loop execute at least once

do
{
a = a + b;
x = x - 1;
} while (x>y);

See also: break, for


Targeting Hardware

For more information on using external clocks, timing specifications for using on-chip RAM or external ROM, please refer to the "Targeting Hardware" section in the Handel-C language reference book/pdf.

A brief description of Off-Chip interfaces: reading from external pins etc, is included. For more detailed descriptions please refer to the "Targetting Hardware" section in hte Handel-C language reference book/pdf.

Targetting Devices

In order to target a specific FPGA, the compiler must be supplied with the FPGA part number. Ultimately, this information is passed to the FPGA place and route tool to inform it of the device it should target.

The syntax for targeting devices consists of two parts - the target family and the target part. The general syntax is:

set family = Family;
set part = Part Number;

Recognised families are :

Family Name
Description
Altera6K | Flex6K series Altera FPGAs
Altera8K | Flex8K series Altera FPGAs
Altera10K | Flex10K series Altera FPGAs
Virtex | Virtex series Xilinx FPGA
Xilinx3000 | 3000 series Xilinx FPGAs
Xilinx4000 | 4000 series Xilinx FPGAs
Xilinx4000A | 4000A series Xilinx FPGAs
Xilinx4000D | 4000D series Xilinx FPGAs
Xilinx4000H | 4000H series Xilinx FPGAs
Xilinx4000E | 4000E series Xilinx FPGAs
Xilinx4000L | 4000L series Xilinx FPGAs
Xilinx4000EX | 4000EX series Xilinx FPGAs
Xilinx4000XL | 4000XL series Xilinx FPGAs
Xilinx4000XV | 4000XV series Xilinx FPGAs

The Part Numberis the complete Xilinx or Altera device string.
For example:

set family = Xilinx4000E;
set part = “4010EPC84-1”;

or for Virtex parts

set family = Xilinx4000XV; // Covers virtex parts as well
set part = "V1000BG560-4";

This instructs the compiler to target a XC4010E device in a PLCC84 package. It also specifies that the device is a -1 speed grade. This last piece of information is required for the timing analysis of your design by the Xilinx tools. The family is used to inform the compiler of which special blocks it may generate. The Xilinx3000 family covers all Xilinx 3000 devices with any suffix.

To target Altera devices:

set family = Altera10K;
set part = “EPF10K20RC240-3”;

This instructs the compiler to target an Altera Flex 10K20 device in a RC240 package. It also specifies that the device is a -3 speed grade. This last piece of information is required for the timing analysis of your design by the Altera Max Plus II tools. Note that when performing place and route on the resulting design, the device and package must also be selected via the menus in the Max Plus II software. Refer to chapter 4 in the Compiler Reference Manual for further details of selecting FPGA part numbers.

Off-chip Interfaces

All off-chip interfaces other than RAMs are declared with the interface keyword. The general syntax of interfaces is as follows:

interface Sort(Types) Name(Args) with {Specs};

Sort field specifies what sort of interface is required.
Types describes the types of values associated with objects coming from the interface.
Name specifies an identifier for the interface.
Args specifies any parameters that the interface may require.
Specs give hardware details of the interface such as chip pin numbers.

Handel-C currently provides the following interface sorts:

Type Identifier
Description
bus_in | Input bus from pins
bus_latch_in | Latched input from pins
bus_clock_in | Clocked input bus from pins
bus_out | Output bus to pins
bus_ts | Bi-directional tri-state bus
bus_ts_latch_in | Bi-directional tri-state bus with latched input
bus_ts_clock_in | Bi-directional tri-state bus with clocked input

Reading from external pins

Six methods for reading from external pins exist. Buses declared as input or bi-directional are capable of reading from external pins. Three sort of input buses can be declared; an asynchronous input bus, a latched input bus and a clocked input bus. Bi-directional buses are detailed in the section entitled Bi-directional data transfers to external pins.

Asynchronous bus: bus_in

The bus_in interface sort allows Handel-C programs to read from external pins. Its general usage is:

interface bus_in(Type) Name() with {data = {Pin List}};

A specific example might be:

interface bus_in(int 4) InBus() with
                        {data = {“P1”, “P2”, “P3”, “P4”}};

This declares a bus connected to pins P1, P2, P3 and P4 where pin P1 is the most significant bit and pin P4 is the least significant bit. Reading the bus is performed by accessing the identifier Name.in as a variable which will return the value on those pins at that clock edge.
For example:

int 4 x;
x = InBus.in;

This sets the variable x to the value on the external pins. The type of InBus.in is int 4 as specified in the type list after the bus_in keyword.

Clocked and Latched buses: bus_latch_in, bus_clock_in

The bus_latch_in interface sort is similar to the bus_in interface sort but allows the input to be latched on a condition. This may be required to sample the signal at particular times.
The bus_clock_in interface sort is similar to the bus_in interface sort but allows the input to be clocked continuously from the Handel-C global clock.
Their general usage is:

interface bus_latch_in(Type) Name(Condition)
        with {data = {Pin List}};
interface bus_clock_in(Type) Name() with {data = {Pin
        List}};

Bus_latch_in usage is exactly like the bus_in interface sort except that Condition specifies a signal that is used to clock the input latches in the FPGA. The rising edge of this signal clocks the external signal to the internal value.
Bus_clock_in usage is exactly like the bus_in interface sort. The rising edge of the Handel-C clock clocks the external signal to the internal value.
For example:

int 1 get;
int 4 x;

interface bus_latch_in(int 4) InBus(get) with
                              {data = {“P1”, “P2”, “P3”, “P4”}};
interface bus_clock_in(int 4) InBus2() with
                              {data = {“P1”, “P2”, “P3”, “P4”}};

get = 0;
get = 1; // Latch the external value
x = InBus.in;  // Read the latched value
x = inBus2.in; // Read the clock latched value

Writing to External Pins

bus_out

The bus_out interface sort allows Handel-C programs to write to external pins. Its general usage is:

interface bus_out() Name(Expression) with {data = {Pin List}};

A specific example might be:

interface bus_out () OutBus(x+y) with
                     {data = {“P1”, “P2”, “P3”, “P4”}};

This declares a bus connected to pins 1, 2, 3 and 4 where pin 1 is the most significant bit and pin 4 is the least significant bit. The value appearing on the external pins is the value of the expression x + y at all times.

Bi-directional Data Transfer

Three forms of bi-directional transfers exist; an asynchronous sort, a clocked and a latched sort.

Asynchronous bi-directonal transfers: bus_ts

The bus_ts interface sort allows Handel-C programs to read or write from external pins. Its general usage is:

interface bus_ts (Type) Name(Value, Condition)
                        with {data = {Pin List}};

Here, Value and Condition are two expressions. Value refers to the value to output on the pins and Condition refers to the condition for driving the pins. When the second expression is non-zero (i.e. true), the value of the first expression is driven on the pins. When the value of the second expression is zero, the pins are tri-stated and the value of the external bus can be read using the identifier Name.in in much the same way that bus_in interfaces work.
A specific example might be:

int 1 enable;
int 4 x;
interface bus_ts(int 4) BiBus(x+1, enable==1)
                        with {data = {“P1”, “P2”, “P3”, “P4”}};

enable = 0;   // Tri-state the pins
x = BiBus.in; // Read the value
enable = 1;   // Drive x+1 onto the pins

This example reads the value of the external bus into variable x and then drives the value of x + 1 onto the external pins. The type of BiBus.in is int 4 as specified in the type list after the bus_ts keyword.

Clocked and Latched bi-directional transfers: bus_ts_clock_in, bus_ts_latch_in

Bi-directional latched and clocked transfers can be declared as:

interface bus_ts_latch_in (Type) Name(Value,
        Condition, Clock)
with {data = {Pin List}};

interface bus_ts_clock_in (Type) Name(Value, Condition)
with {data = {Pin List}};

Take care when driving tri-state buses that the FPGA and another device on the bus cannot drive simultaneously as this may result in damage to one or both of them.


RC1000-PP Functions

This manual provides details of the functions provided in the RC1000-PP host support library and FPGA macro reference. Details of usage of the support functions are given in the RC1000-PP Software User Guide and details of the hardware are given in the RC1000-PP Hardware Reference Manual. Extensive references are made throughout this document to these companion documents.

The RC1000-PP host support software provides a host driver and library to simplify the process of initialising and talking to the hardware. A number of example programs and utilities are also provided as a starting point for the development of your own applications. Refer to the RC1000-PP Software User Guide for details of these examples and utilities.

The support software provides a number of groups of host functions:

Initialisation functions
Functions to handle FPGA configuration files
Functions to control the RC1000-PP programmable clocks
Functions to transfer data to and from the RC1000-PP FPGA
Functions to help with error checking and debugging

The software support package consits of:

A device driver
A static C library which can be linked to host programs
A set of Handel-C macros for use with FPGA programs.

Host Functions Reference

Initializing and Cleanup
PP1000CloseCard
PP1000GetCard
PP1000OpenCards
PP1000OpenFirstCard

Clocking
PP1000SetClockRate
PP1000StartVClock
PP1000StepVClock
PP1000StopVClock

FPGA Configuration
PP1000ConfigureFPGA
PP1000ConfigureFromFile
PP1000FreeImage
PP1000LoadFile
PP1000RegisterImage

Memory Manipulation
PP1000CloseDMAChannel
PP1000DoDMA
PP1000GetBankStatus
PP1000ReleaseMemoryBank
PP1000RequestMemoryBank
PP1000Setup2DDMAChannel
PP1000SetupDMAChannel

Miscellaneous
PP1000GetCardInfo
PP100ReadGPI
PP1000ReadStatus
PP1000ResetFPGA
PP1000SetGPO
PP1000SetTimeOut
PP1000WriteControl

Error Handling
PP1000InstallErrorHandler
PP1000StatusToString

FPGA Macro Reference

Handel-C Macros for the RC1000-PP

PP1000ReadBank# | Preprocessor Macros
PP1000ReadControl | PP1000LEDOff
PP1000ReadGPO | PP1000LEDOn
PP1000ReleaseMemoryBank | PP1000SetLEDs
PP1000RequestMemoryBank |
PP1000SetGPI |
PP1000WriteBank# |
PP1000WriteStatus |

The contents here are an abstract of the RC1000-PP manuals.
All rights belongs to Embedded Solutions Ltd.
Please read the disclaimer.

Embedded Solutions Ltd.

Help file compiled by Seng Shay Ping
3/11/99 Version 2.1a


RC1000PP Host: Initialising and Closing Functions

RC1000-PP Host:
Initialising and Closing Functions

PP1000CloseCard

PP1000_STATUS PP1000CloseCard(
PP1000_HANDLE Card);

Arguments
Card | Handle of card to close.
Return Values
PP1000_SUCCESS | Success.
PP1000_INVALID_HANDLE | Card is not a valid card handle.
Description

This function is used to close a handle for a card and free the card for use elsewhere. It should be called after an application has finished with the board to allow the support software to clean up.

Card must be a valid handle returned by PP1000OpenCard() or PP1000OpenFirstCard().

PP1000GetCards

PP1000_STATUS PP1000GetCards(
unsigned * NumCards,
PP1000_DEVICE_COUNT ** CardIDs);

Arguments
NumCards | Pointer to location to receive number of cards in the system.
CardIDs | Pointer to location to receive list of cards in the system.
Return Values
PP1000_SUCCESS | Success.
PP1000_NO_DRIVER | RC1000-PP driver is not installed.
PP1000_INTERNAL_ERROR | Error while talking to driver.
PP1000_NO_MEMORY | Not enough memory to complete operation.
Description

This function is used to retrieve information about the number of RC1000-PP cards in a system. The function returns the total number of cards via the NumCards parameter. It also returns a list of the card IDs and the number of cards with each card ID via the CardIDs parameter. To display all the cards in a system you could use the following Handel C code:

unsigned long NumCards;
PP1000_DEVICE_COUNT *Present;
unsigned long Count;

PP1000GetCards(&NumCards, &Present);
printf("Number of cards = %d\n", NumCards);
for (Count=0; NumCards>0; Count++) {
printf("Card ID : %d, ", Present[Count].CardID);
printf("number present : %d\n", Present[Count].Count);
NumCards-=Present[Count].Count;
}
free(Present);

Note that it is the caller's responsibility to free the array pointed to by CardIDs.

PP1000OpenCard

PP1000_STATUS PP1000OpenCard(
PP1000_DEVICE_NUM CardID,
PP1000_HANDLE * Card);

Arguments
CardID | ID of card to open
Card | Pointer to location to receive handle of open card
Return Values
PP1000_SUCCESS | Success.
PP1000_NULL_POINTER | Card is a NULL pointer.
PP1000_INTERNAL_ERROR | Error while talking to driver.
PP1000_NO_MEMORY | Not enough memory to complete operation.
PP1000_INVALID_CARDID | No cards with ID of CardID found.
PP1000_NO_FREE_CARDS | No free cards with ID of CardID found.
Description

This function is used to obtain a handle to an RC1000-PP card in the system. The card is identified by its card ID passed via the CardID parameter.

In the event of there being more than one card with the same ID, the function will open the first card with the correct ID that it finds that has not already been opened.

The handle returned in the Card parameter should be used in all further functions to access this board.

When access to the card is no longer required, you should call the PP1000CloseCard() function to free the handle and allow other programs access to the card.

PP1000OpenFirstCard

PP1000_STATUS PP1000OpenFirstCard(
PP1000_HANDLE * Card);

Arguments
Card | Pointer to location to receive handle of open card
Return Values
PP1000_SUCCESS | Success.
PP1000_NULL_POINTER | Card is a NULL pointer.
PP1000_INTERNAL_ERROR | Error while talking to driver.
PP1000_NO_MEMORY | Not enough memory to complete operation.
PP1000_NO_FREE_CARDS | No free cards with ID of CardID found.
Description

This function is used to obtain a handle to an RC1000-PP card in the system. The card opened is the first free card found in the system. This function should be used when it is not critical which card is opened or when there is only one card in the system.

The handle returned in the Card parameter should be used in all further functions to access this board.

When access to the card is no longer required, you should call the PP1000CloseCard() function to free the handle and allow other programs access to the card.


RC1000PP Host: Memory Manipulation Functions

RC1000-PP Host:
Memory Manipulation Functions

PP1000CloseDMAChannel

PP1000_STATUS PP1000CloseDMAChannel(
PP1000_CHANNEL Channel);

Arguments
Channel | DMA Channel.
Return Values
PP1000_SUCCESS | Success.
PP1000_INVALID_CHANNEL | Channel is not a valid DMA channel handle.
PP1000_TIMEOUT | Operation timed out before banks were granted.
PP1000_INTERNAL_ERROR | Error while talking to driver.
Description

This function is used to free a DMA channel handle that was created with the PP1000SetupDMAChannel() or PP1000Setup2DDMAChannel() functions. The user buffer is also unlocked by this function.

This function times out, if unsuccessful, after the period set for by using PP1000SetTimeOut().

PP1000DoDMA

PP1000_STATUS PP1000DoDMA(
PP1000_CHANNEL Channel);

Arguments
Channel | DMA Channel.
Return Values
PP1000_SUCCESS | Success.
PP1000_INVALID_HANDLE | Card is not a valid card handle.
PP1000_INVALID_CHANNEL | Channel is not a valid DMA channel handle.
PP1000_TIMEOUT | Operation timed out before banks were granted.
PP1000_INTERNAL_ERROR | Error while talking to driver.
PP1000_CARD_BUSY | Error while talking to driver.
Description

This function is used to perform a DMA transfer using a given DMA channel handle. The handle must have been created previously with the PP1000SetupDMAChannel() or PP1000Setup2DDMAChannel() function.

This function times out, if unsuccessful, after the period set for by using PP1000SetTimeOut().

You must ensure that all memory banks required for the transfer have been requested with the PP1000RequestMemoryBanks() before attempting DMA transfers.

PP1000GetBankStatus

PP1000_STATUS PP1000GetBankStatus(
PP1000_HANDLE Card,
short * MaskHost
short * MaskFPGA);

Arguments
Card | Handle of card.
MaskHost

Mask of banks currently owned by host.
MaskFPGA | Mask of banks currently owned by FPGA.
Return Values
PP1000_SUCCESS | Success.
PP1000_INVALID_HANDLE | Card is not a valid card handle.
PP1000_TIMEOUT | Operation timed out before banks were granted.
PP1000_INTERNAL_ERROR | Error while talking to driver.
Description

This function is used to query the ownership of the memory banks on a card. Each mask is a four bit value indicating which banks are currently owned by the host or FPGA. Bit 0 (the LSB) is set to 1 to indicate ownership of bank 0, bit 1 is set to 1 to indicate ownership of bank 1 and so on. Banks cannot be granted to both the FPGA and host at the same time.

MaskHost or MaskFPGA may be set to NULL in which case the respective information is not returned.

Card must be a valid handle returned by PP1000OpenCard() or PP1000OpenFirstCard().

This function times out, if unsuccessful, after the period set for by using PP1000SetTimeOut().

PP1000ReleaseMemoryBank

PP1000_STATUS PP1000ReleaseMemoryBank(
PP1000_HANDLE Card
short Mask);

Arguments
Card | Handle of card.
Mask | Mask of banks to release.
Return Values
PP1000_SUCCESS | Success.
PP1000_INVALID_HANDLE | Card is not a valid card handle.
PP1000_TIMEOUT | Operation timed out before banks were granted.
PP1000_INTERNAL_ERROR | Error while talking to driver.
Description

This function is used to release ownership of one or more memory banks on a card.

Mask is a four bit value indicating which banks should be released. Bit 0 (the LSB) should be set to 1 to release bank 0, bit 1 should be set to 1 to release bank 1 and so on. Banks cannot be granted to both the FPGA and host at the same time so you should ensure that banks are released by the host program when trying to request them for the FPGA.

Card must be a valid handle returned by PP1000OpenCard() or PP1000OpenFirstCard().

This function times out, if unsuccessful, after the period set for by using PP1000SetTimeOut().

PP1000RequestMemoryBank

PP1000_STATUS PP1000RequestMemoryBank(
PP1000_HANDLE Card
short Mask);

Arguments
Card | Handle of card.
Mask | Mask of banks to request.
Return Values
PP1000_SUCCESS | Success.
PP1000_INVALID_HANDLE | Card is not a valid card handle.
PP1000_TIMEOUT | Operation timed out before banks were granted.
PP1000_INTERNAL_ERROR | Error while talking to driver.
PP1000_CARD_BUSY | Error while talking to driver.
Description

This function is used to request access to one or more memory banks on a card. The function will block and return only when the banks have been granted to the host or when a timeout occurs.

Mask is a four bit value indicating which banks should be requested. Bit 0 (the LSB) should be set to 1 to request bank 0, bit 1 should be set to 1 to request bank 1 and so on. Banks cannot be granted to both the FPGA and host at the same time so you should ensure that banks are released by the FPGA program when trying to request them for the host.

Card must be a valid handle returned by PP1000OpenCard() or PP1000OpenFirstCard().

This function times out, if unsuccessful, after the period set for by using PP1000SetTimeOut().

PP1000Setup2DDMAChannel

PP1000_STATUS PP1000Setup2DDMAChannel(
PP1000_HANDLE Card,
void * HostAddress,
unsigned long HostPitch,
unsigned long HostSpace,
unsigned long CardOffset,
unsigned long CardPitch,
unsigned long Width,
unsigned long Height,
PP1000_DMA_DIRECTION Direction,
PP1000_Channel * Channel);

Arguments
Card | Handle of card.
HostAddress | Pointer to buffer on host to DMA to/from.
HostPitch | Number of bytes between line start points in host buffer.
HostSpace | Flag specifying whether HostAddress is a virtual or physical address.
CardOffset | Offset into RC1000-PP RAM to DMA to/from.
CardPitch | Number of bytes between line start points in card and memory.
Width | Width of 2D transfer in bytes.
Height | Height of 2D transfer.
Direction | Direction of transfer.
Channel | Pointer to location to receive DMA channel handle.
Return Values
PP1000_SUCCESS | Success.
PP1000_INVALID_HANDLE | Card is not a valid card handle.
PP1000_INVALID_ALIGNMENT | Host or card address is not 4 byte aligned.
PP1000_INVALID_DIRECTION | Direction is not PP1000_LOCAL2PCI or PP1000_PCI2LOCAL.
PP1000_INVALID_ADDRESS_SPACE | HostSpace is not PP1000_VIRTUAL or PP1000_PHYSICAL.
PP1000_NULL_POINTER | Channel is a NULL pointer.
PP1000_INTERNAL_ERROR | Error while talking to driver.
PP1000_NO_MEMORY | Not enough physical memory to create channel handle.
PP1000_LOCK_FAILED | Not enough physical memory to lock buffer.
Description

This function is used to prepare a user buffer for 2 dimensional DMA transfers to or from a card. The buffer is locked in physical memory ready for transfers by the DMA controller on the RC1000-PP.

Card must be a valid handle returned by PP1000OpenCard() or PP1000OpenFirstCard().

HostAddress points to the user host buffer. This address must be aligned to a 4 byte boundary. The address can either be a virtual address (i.e. a pointer to a user buffer) or a PCI physical address. Use of a physical address allows the RC1000-PP to directly DMA to or from a second PCI device. The HostSpace flag should be set to PP1000_VIRTUAL if HostAddress is a virtual address or PP1000_PHYSICAL if HostAddress is a physical address.

Direct card to card transfers are made possible by retrieving the physical address returned by PP1000GetCardInfo() for the slave card and passing that base address (plus any required offset) into this function as the HostAddress parameter. The DMA controller on the card whose handle is passed into the PP1000Setup2DDMAChannel() function will then be used as a PCI bus master to transfer the data.

Care should be taken when DMAing to or from a physical address as using an illegal physical address can hang the host computer.

HostPitch specifies the number of bytes between the start of the lines of the transfer in the host buffer. This value must be a multiple of 4 bytes.

CardOffset specifies the offset (in bytes) into the card memory to DMA to/from. This offset must be 4 byte aligned.

CardPitch specifies the number of bytes between the start of the lines of the transfer in the card memory. This value must be a multiple of 4 bytes.

Width specifies the width of the 2D transfer in bytes. This value must be 4 byte aligned. Height specifies the number of lines to transfer.

Direction should be set to PP1000_PCI2LOCAL for a transfer from host or remote card to this card or PP1000_LOCAL2PCI for a transfer from this card to host or remote card.

The channel handle returned by this function can be used in future calls to PP1000DoDMA() . Keeping DMA channels open for a long period of time can degrade system performance. You should call PP1000CloseDMAChannel() as soon as possible to minimise these effects

A 2D transfer can be illustrated with the following figure.

The buffer to be transferred is described by 4 parameters: start address, line pitch, width and height. The source and destination width and height must be the same and are both set to the values of the Width and Height parameters. The source and destination base addresses and line pitches can be set separately.

PP1000SetupDMAChannel

PP1000_STATUS PP1000SetupDMAChannel(
PP1000_HANDLE Card,
void * HostAddress,
unsigned long CardOffset,
unsigned long Length,
PP1000_DMA_DIRECTION Direction,
PP1000_Channel * Channel);

Arguments
Card | Handle of card.
HostAddress | Pointer to buffer on host to DMA to/from.
CardOffset | Offset into RC1000-PP RAM to DMA to/from.
Length | Number of bytes to transfer.
Direction | Direction of transfer.
Channel | Pointer to location to receive DMA channel handle.
Return Values
PP1000_SUCCESS | Success.
PP1000_INVALID_HANDLE | Card is not a valid card handle.
PP1000_INVALID_ALIGNMENT | Host or card address is not 4 byte aligned.
PP1000_INVALID_DIRECTION | Direction is not PP1000_LOCAL2PCI or PP1000_PCI2LOCAL.
PP1000_NULL_POINTER | Channel is a NULL pointer.
PP1000_INTERNAL_ERROR | Error while talking to driver.
PP1000_NO_MEMORY | Not enough physical memory to create channel handle.
PP1000_LOCK_FAILED | Not enough physical memory to lock buffer.
Description

This function is used to prepare a user buffer for DMA transfers to or from a card. The buffer is locked in physical memory ready for transfers by the DMA controller on the RC1000-PP.

Card must be a valid handle returned by PP1000OpenCard() or PP1000OpenFirstCard().

HostAddress points to the user host buffer. This address must be aligned to a 4 byte boundary.

CardOffset specifies the offset (in bytes) into the card memory to DMA to/from. This offset must be 4 byte aligned.

Length specifies how many bytes should be transferred. This value must be 4 byte aligned.

Direction should be set to PP1000_PCI2LOCAL for a transfer from host to card or PP1000_LOCAL2PCI for a transfer from card to host.

The channel handle returned by this function can be used in future calls to PP1000DoDMA().

Keeping DMA channels open for a long period of time can degrade system performance. You should call PP1000CloseDMAChannel() as soon as possible to minimise these effects


RC1000PP Host: FPGA Configuration Functions

RC1000-PP Host:
FPGA Configuration Functions

PP1000ConfigureFPGA

PP1000_STATUS PP1000ConfigureFPGA(
PP1000_HANDLE Card,
PP1000_IMAGE Image);

Arguments
Card

Handle of card to configure.
Image | Handle of configuration image to use.
Return Values
PP1000_SUCCESS | Success.
PP1000_FPGA_MISMATCH | File is not for the FPGA fitted to this card.
PP1000_INVALID_HANDLE | Card is not valid card handle.
PP1000_INVALID_IMAGE | Image is not a valid handle.
PP1000_INTERNAL_ERROR | Error while talking to driver.
PP1000_TIMEOUT | Operation timed out before configuration could complete.
Description

This function is used to configure the FPGA on a card with a configuration image. The configuration image should be registered with the support software either with the PP1000LoadFile() function or with the PP1000RegisterImage() function.

If there is an FPGA part mismatch between the configuration image and the FPGA on the card, PP1000_FPGA_MISMATCH will be returned.

This function times out, if unsuccessful, after the period set for by using PP1000SetTimeOut().

PP1000ConfigureFromFile

PP1000_STATUS PP1000ConfigureFromFile(
PP1000_HANDLE Card,
char * FileName);

Arguments
Card

Handle of card to configure.
FileName | Name of configuration file.
Return Values
PP1000_SUCCESS | Success.
PP1000_FILE_NOT_FOUND | Could not open file FileName.
PP1000_FILE_ACCESS_ERROR | Error while reading file.
PP1000_INVALID_FILE | File not correct format.
PP1000_NO_MEMORY | Not enough memory to load file.
PP1000_INVALID_PART_TYPE | File is for an unrecognised FPGA.
PP1000_FPGA_MISMATCH | File is not for the FPGA fitted to this card.
PP1000_INVALID_HANDLE | Card is not valid card handle.
PP1000_INTERNAL_ERROR | Error while talking to driver.
PP1000_TIMEOUT | Operation timed out before configuration could complete.
Description

This function is used to configure the FPGA on a card from a configuration image file.

The file must be in Xilinx BIT format. The card to be configured is specified with the Card parameter which is obtained by a call to the PP1000OpenCard() or PP1000OpenFirstCard() function.

The FileName parameter is a string containing the full path name of the configuration file to use.

This function times out, if unsuccessful, after the period set for by using PP1000SetTimeOut().

PP1000FreeImage

PP1000_STATUS PP1000FreeImage(
PP1000_IMAGE Image);

Arguments
Image | Handle of configuration image to use.
Return Values
PP1000_SUCCESS | Success.
PP1000_INVALID_IMAGE | Image is not a valid file handle.
Description

This function is used to free the handle of an FPGA configuration image when it is no longer required.

PP1000LoadFile

PP1000_STATUS PP1000LoadFile(
char * FileName,
PP1000_IMAGE * Image);

Arguments
FileName

Name of configuration file.
Image | Pointer to location to receive configuration image handle.
Return Values
PP1000_SUCCESS | Success.
PP1000_FILE_NOT_FOUND | Could not open file FileName.
PP1000_FILE_ACCESS_ERROR | Error while reading file.
PP1000_INVALID_FILE | File not in correct format.
PP1000_NO_MEMORY | Not enough memory to load file.
PP1000_INVALID_PART_TYPE | File is for an unrecognised FPGA.
Description

This function is used to load an FPGA configuration image into host RAM and obtains a handle for that image. This handle will be required by the PP1000ConfigureFPGA() function when you wish to configure the FPGA. The file must be in Xilinx BIT format.

The FileName parameter is a string containing the full name of the file to read.

The PP1000LoadFile() function will attempt to automatically determine the intended part type of the configuration image from the file.

PP1000RegisterImage

PP1000_STATUS PP1000RegisterImage(
unsigned char * Buffer,
unsigned long BufferLength
PP1000_IMAGE * Image);

Arguments
Buffer

Pointer to start of configuration image.
BufferLength | Length of configuration image in bytes.
Image | Pointer to location to receive configuration image handle.
Return Values
PP1000_SUCCESS | Success.
PP1000_NULL_POINTER | Image or Buffer is a NULL pointer.
PP1000_NO_MEMORY | Not enough memory to load file.
PP1000_INVALID_PART_TYPE | File is for an unrecognised FPGA.
Description

This function is used to register a configuration image with the support software and obtain a handle for that image. This handle will be required by the PP1000ConfigureFPGA() function when you wish to configure the FPGA.

The FPGA part type is determined automatically from the buffer length.

The gencfg utility can be used to generate suitable information for this function from a Xilinx .bit file. Refer to the Software Reference Manual for details of this utility.


RC1000PP Host: Miscellaneous Functions

RC1000-PP Host:
Miscellaneous Functions

PP1000GetCardInfo

PP1000_STATUS PP1000GetCardInfo(
PP1000_HANDLE Card
PP1000_CARD_INFO * Info);

Arguments
Card | Handle of card to close.
Info | Pointer to card information structure to be filled in.
Return Values
PP1000_SUCCESS | Success.
PP1000_INVALID_HANDLE | Card is not a valid card handle.
PP1000_NULL_POINTER | Info is a NULL pointer.
PP1000_INTERNAL_ERROR | Error while talking to driver.
Description

Card must be a valid handle returned by PP1000OpenCard() or PP1000OpenFirstCard().

This function is used to obtain information about an open card. The card information structure that is filled in is defined as follows:

typedef struct
{
PP1000_DEVICE_NUM
            CardID;
unsigned long     PMC1Fitted;
unsigned long     PMC2Fitted;
unsigned long     RAMBankFitted[4];
unsigned long     RAMBankSpace[4];
PP1000_FPGA_TYPE  FPGAType;
unsigned long     PhysicalMemoryBase;
unsigned long *   MemoryBase;
unsigned long     BoardRevision;
unsigned long     LogicRevision;
unsigned long     SerialNum;
unsigned long     Timeout;
} PP1000_CARD_INFO;

CardID is the ID of the card. This will be the value passed to PP1000OpenCard() if that function was used to open the card handle.

PMC1Fitted and PMC2Fitted are non zero if the respective PMC site is occupied by a PMC compliant daughter module.

RAMBankFitted[] is filled in with the size of each of the RAM banks on the board. The size is given in bytes.

RAMBankSpace[] is filled in with the space assigned to each memory bank. This will be greater than or equal to the value in RAMBankFitted[]. These values should be used to determine the offset of each RAM bank. The size is given in bytes.

FPGAType is filled in with the type of FPGA fitted to the board. Currently, this can be one of the following:

PP1000_FPGA_4085XL
PP1000_FPGA_40150XV
PP1000_FPGA_40200XV
PP1000_FPGA_40250XV
PP1000_FPGA_V1000
PP1000_FPGA_UNKNOWN

PP1000_FPGA_UNKNOWN should only be returned when the card is not functioning correctly.

PhysicalMemoryBase is filled in with the base address of the card's memory banks on the PCI bus. This can be used for card to card DMA transfers (see the PP1000Setup2DDMAChannel() function) or for direct access by another PCI bus master device.

MemoryBase is filled in with a virtual pointer to the RAM banks on the RC1000-PP. This address may be used to read and write the SRAM on the board directly. Accesses should be made as 32 bit words and aligned to 32 bit boundaries. The size of the window is given by the sum of the 4 values in RAMBankSpace[]. Memory banks must be requested with the PP1000RequestMemoryBank() function before they can be accessed.

BoardRevision and LogicRevision are filled in with version numbers for the board and glue logic. Version numbers are 8 bit hexadecimal numbers where the most significant nibble is the major version and the least significant nibble is the minor version. For example, version 2.3 is represented by 0x23.

SerialNum is filled in with the serial number of the card. The serial number is factory set and is guaranteed to be a unique number. (The card ID can be set by the user and so there can be multiple cards with the same ID in one system).

Timeout is filled in with the current value for the timeout on a card in milliseconds. The timeout is used by the library in blocking operations to return when the operation does not complete within the specified time.

PP1000ReadGPI

PP1000_STATUS PP1000ReadGPI(
PP1000_HANDLE Card,
unsigned long * Value);

Arguments
Card | Handle of card to close.
Value | Pointer to location to receive value from GPI pin.
Return Values
PP1000_SUCCESS | Success.
PP1000_INVALID_HANDLE | Card is not a valid card handle.
PP1000_NULL_POINTER | Value is NULL.
PP1000_INTERNAL_ERROR | Error while talking to driver.
Description

This function is used to read the state of the general purpose input (GPI) pin. The location pointed to by Value will be set to 1 if the FPGA has set the GPI pin or zero if the FPGA has cleared the GPI pin. The FPGA can set the state of the GPI pin using the PP1000SetGPI() Handel-C macro procedure.

Card must be a valid handle returned by PP1000OpenCard() or PP1000OpenFirstCard().

PP1000ReadStatus

PP1000_STATUS PP1000ReadStatus(
PP1000_HANDLE Card,
unsigned char * Status);

Arguments
Card | Handle of card to close.
Status | Pointer to location to receive value from status port.
Return Values
PP1000_SUCCESS | Success.
PP1000_INVALID_HANDLE | Card is not a valid card handle.
PP1000_TIMEOUT | Operation timed out before FPGA read from port.
PP1000_INTERNAL_ERROR | Error while talking to driver.
PP1000_CARD_BUSY | Card is not ready..
Description

This function is used to read from the status port on a card. The function will block until the FPGA has written to the status port. The FPGA can write to the status port using the PP1000WriteStatus() Handel-C macro procedure.

Status may be a NULL pointer in which case the synchronisation between FPGA and host will occur but the data will be dropped.

Card must be a valid handle returned by PP1000OpenCard() or PP1000OpenFirstCard().

This function times out, if unsuccessful, after the period set for by using PP1000SetTimeOut().

PP1000ResetFPGA

PP1000_STATUS PP1000ResetFPGA(
PP1000_HANDLE Card);

Arguments
Card | Handle of card to close.
Return Values
PP1000_SUCCESS | Success.
PP1000_INVALID_HANDLE | Card is not a valid card handle.
PP1000_INTERNAL_ERROR | Error while talking to driver.
PP1000_TIMEOUT | Operation timed out before reset could complete.
Description

This function is used to pulse the F_RST_L pin on an FPGA. This pin can be used by the user FPGA program as a reset line since it has no effect on any other part of the RC1000-PP hardware or support software.

Card must be a valid handle returned by PP1000OpenCard() or PP1000OpenFirstCard().

This function times out, if unsuccessful, after the period set for by using PP1000SetTimeOut().

PP1000SetGPO

PP1000_STATUS PP1000SetGPO(
PP1000_HANDLE Card,
unsigned long Value);

Arguments
Card | Handle of card to close.
Value | Non-zero to set GPO, zero to clear GPO.
Return Values
PP1000_SUCCESS | Success.
PP1000_INVALID_HANDLE | Card is not a valid card handle.
PP1000_INTERNAL_ERROR | Error while talking to driver.
Description

This function is used to set the state of the general purpose output (GPO) pin. When Value is non-zero, this pin on the FPGA will be set to 1, when Value is zero, this pin on the FPGA will be set to zero. This pin can be read on the FPGA using the PP1000ReadGPO() Handel-C macro expression.

Card must be a valid handle returned by PP1000OpenCard() or PP1000OpenFirstCard().

PP1000SetTimeOut

PP1000_STATUS PP1000SetTimeOut(
PP1000_HANDLE Card
unsigned long Time);

Arguments
Card | Handle of card to set timeout on.
Time | Length of timeout in milliseconds.
Return Values
PP1000_SUCCESS | Success.
PP1000_INVALID_HANDLE | Card is not a valid card handle.
Description

Card must be a valid handle returned by PP1000OpenCard() or PP1000OpenFirstCard().

The RC1000-PP support software uses timeouts on operations that can block to force completion of functions even if the operation is not complete. This function is used to set the length of the timeout used on a board.

Timeouts may be disabled on a card by specifying a length of PP1000_TIMEOUT_INFINITE.

PP1000WriteControl

PP1000_STATUS PP1000WriteControl(
PP1000_HANDLE Card,
unsigned char Control);

Arguments
Card | Handle of card to close.
Control | Value to write to card.
Return Values
PP1000_SUCCESS | Success.
PP1000_INVALID_HANDLE | Card is not a valid card handle.
PP1000_TIMEOUT | Operation timed out before FPGA read from port.
PP1000_INTERNAL_ERROR | Error while talking to driver.
PP1000_CARD_BUSY | Card is not ready.
Description

This function is used to write to the control port on a card. The function will block until the FPGA has read from the control port. The FPGA can read from the control port using the PP1000ReadControl() Handel-C macro procedure.

Card must be a valid handle returned by PP1000OpenCard() or PP1000OpenFirstCard().

This function times out, if unsuccessful, after the period set for by using PP1000SetTimeOut().


RC1000PP Host Error Handling Functions

RC1000-PP Host:
Error Handling Functions

PP1000InstallErrorHandler

PP1000_STATUS PP1000InstallErrorHandler(
PP1000_HANDLER_FUNCTION Handler);

Arguments
Handler | Error handler function
Return Values
PP1000_SUCCESS | Success.
Description

This function is used to install a user defined function that will be called whenever the RC1000-PP support library encounters an error condition. The prototype of the handler function should be:

void Handler(char *FnName, PP1000_STATUS Status);

When this function is called, FnName will point to a string containing the name of the calling function and Status will contain the error code. Should the handler function return, the RC1000-PP function that generated the error will return to the main program with the same error condition.

Passing NULL as the value for Handler will un-install the error handler. A suggested error handling function is as follows:

void Handler(char *FnName, PP1000_STATUS Status)
{
unsigned char Buffer[1024];

PP1000StatusToString(Status, Buffer, sizeof(Buffer));
printf("\n%s - %s\n", FnName, Buffer);

exit(1);
}

PP1000StatusToString

PP1000_STATUS PP1000StatusToString(
PP1000_Status Status,
char * String,
unsigned long Length);

Arguments
Status | Return code to decode.
String | Pointer to buffer to receive error string.
Length | Length to buffer to receive string.
Return Values
PP1000_SUCCESS | Success.
PP1000_NULL_POINTER | String is a NULL pointer.
PP1000_INVALID_ARGUMENT | Length is zero.
Description

This function is used to obtain a text error string for a return code. The zero terminated string will be written into the buffer pointed to by String. The maximum length of the error string (including zero termination) will be Length bytes. If Status is not a recognised return code, a string of “Unknown Error” will be returned.


RC1000-PP Host: Clocking Functions

PP1000SetClockRate

PP1000_STATUS PP1000SetClockRate(
PP1000_HANDLE Card,
PP1000_CLOCK Clock,
double Rate);

Arguments
Card | Handle of card to set clock on.
Clock | Identifier of clock to program.
Rate | Frequency (in Hertz) to set clock to.
Return Values
PP1000_SUCCESS | Success.
PP1000_INVALID_HANDLE | Card is not valid card handle.
PP1000_INVALID_CLOCK_RATE | Rate is out of range.
PP1000_INVALID_CLOCK | Clock is invalid.
PP1000_INTERNAL_ERROR | Error while talking to driver.
Description

This function is used program one of the clocks on a card. The value of Clock can be either PP1000_MCLK or PP1000_VCLK.

When the Clock parameter is set to PP1000_MCLK, the MCLK input is set to the frequency specified by the Rate parameter provided that JP2 is linking positions 2 and 3. When JP2 is in positions 1 and 2, the MCLK pin is fed from the clock in connector (J10). Refer to the hardware reference manual for further details of jumper settings.

When the Clock parameter is set to PP1000_VCLK, the VCLK input is set to the frequency specified by the Rate parameter provided that JP3 is linking positions 2 and 3. When JP3 is in positions 1 and 2, the VCLK pin is fed from the local PCI bus clock. (Set at 33MHz.) Refer to the hardware reference manual for further details of jumper settings.

Setting the Rate of VCLK will automatically start the clock running. Refer to the PP1000StopVClock() function for details of how to stop the signal on the VCLK pin.

The value of Rate can be anything between 400kHz (4x10e5 ) and 100MHz (1x10e8 ). The clock will be set to the closest obtainable frequency.

The value of Card is obtained from a call to one of the initialisation functions, PP1000OpenCard() or PP1000OpenFirstCard().

You should avoid setting the MCLK and VCLK outputs from the clock generator to frequencies which are close together to avoid noise on the clock.

PP1000StartVClock

PP1000_STATUS PP1000StartVClock(
PP1000_HANDLE Card);

Arguments
Card | Handle of card to set clock on.
Return Values
PP1000_SUCCESS | Success.
PP1000_INVALID_HANDLE | Card is not valid card handle.
PP1000_INTERNAL_ERROR | Error while talking to driver.
Description

This function is used start the signal on the VCLK input of the FPGA provided that JP3 is linking positions 2 and 3. When JP3 is in positions 1 and 2, the VCLK pin is fed from the local PCI bus clock which is set at 33MHz. Refer to the hardware reference manual for further details of jumper settings.

When the VCLK signal is started, it will return to the rate set by the last call to PP1000SetClockRate() with a parameter of PP1000_VCLK..

The value of Card is obtained from a call to one of the initialisation functions, PP1000OpenCard() or PP1000OpenFirstCard().

PP1000StepVClock

PP1000_STATUS PP1000StepVClock(
PP1000_HANDLE Card);

Arguments
Card | Handle of card to set clock on.
Return Values
PP1000_SUCCESS | Success.
PP1000_INVALID_HANDLE | Card is not valid card handle.
PP1000_INTERNAL_ERROR | Error while talking to driver.
Description

This function is used to single step the signal on the VCLK input of the FPGA provided that JP3 is linking positions 2 and 3. When JP3 is in positions 1 and 2, the VCLK pin is fed from the local PCI bus clock which is set at 33MHz. Refer to the hardware reference manual for further details of jumper settings.

Before the VCLK pin can be single stepped, it must be stopped with a call to PP1000StopVClock() .

The value of Card is obtained from a call to one of the initialisation functions, PP1000OpenCard() or PP1000OpenFirstCard().

PP1000StopVClock

PP1000_STATUS PP1000StopVClock(
PP1000_HANDLE Card);

Arguments
Card | Handle of card to set clock on.
Return Values
PP1000_SUCCESS | Success.
PP1000_INVALID_HANDLE | Card is not valid card handle.
PP1000_INTERNAL_ERROR | Error while talking to driver.
Description

This function is used stop the signal on the VCLK input of the FPGA provided that JP3 is linking positions 2 and 3. When JP3 is in positions 1 and 2, the VCLK pin is fed from the local PCI bus clock which is set at 33MHz. Refer to the hardware reference manual for further details of jumper settings.

When the VCLK signal is stopped, it will be held high until either the PP1000StartVClock() or PP1000SetClockRate() function is called.

The value of Card is obtained from a call to one of the initialisation functions, PP1000OpenCard() or PP1000OpenFirstCard().


RC1000PP FPGA Macro Reference

RC1000-PP:
FPGA Macro Reference

Each macro description lists the arguments and widths required and values returned as well as timing details of the macros.The macros and other definitions are provided in the pp1000.h header file which must be included at the start of your Handel-C program.

Preprocessor Macros

Before including the pp1000.h header file you must define some pre-processor macros describing the configuration of the card. These macros are described in full in the Software Reference Manual and are summarised in the table below.

Configuration items | Macros to Define
Clock division factor PP1000_DIVIDE1
PP1000_DIVIDE3
PP1000_DIVIDE4
Clock source | PP1000_CLOCK
External RAM width PP1000_8BIT_RAMS
PP1000_32BIT_RAMS

For example, to set the board up with a clock source of MCLK divided by 4 and with 32 bit access to the external memory banks, the following code should appear at the start of the Handel-C program.

#define PP1000_DIVIDE4
#define PP1000_CLOCK PP1000_MCLK
#define PP1000_32BIT_RAMS
#include “pp1000.h”

PP1000LEDOn

PP1000LEDOn(Index);

Arguments
Index Index of LED to switch on. Should be between 0 and 7 inclusive.
Return Values
None.
Execution Time
One clock cycle.
Description

This macro procedure will turn a single LED on.

This macro procedure should not be called in parallel with itself or PP1000LEDOff() if Index is the same or with the PP1000SetLEDs() macro procedure.

PP1000LEDOff

PP1000LEDff(Index);

Arguments
Index Index of LED to switch off. Should be between 0 and 7 inclusive.
Return Values
None.
Execution Time
One clock cycle.
Description

This macro procedure will turn a single LED off.

This macro procedure should not be called in parallel with itself or PP1000LEDOn() if Index is the same or with the PP1000SetLEDs() macro procedure.

PP1000ReadBank#

PP1000ReadBank0(Reg,Addr);
PP1000ReadBank1(Reg,Addr);
PP1000ReadBank2(Reg,Addr);
PP1000ReadBank3(Reg,Addr);

Arguments
Reg | Register to read data into. Must be 8 or 32 bits wide.
Addr | Address to read data from. Must be 19, 21 or 23 bits wide.
Return Values
Reg is set to contents of memory bank.
Execution Time
One clock cycle.
Description

These macro procedures should be used to read from the external memory banks on an RC1000-PP card. They can access any banks in parallel but the memory banks must have been granted to the FPGA before hand. To request memory banks use the PP1000RequestMemoryBank() macro procedure.

If you define 8 bit access to memory using the PP1000_8BIT_RAMS preprocessor macro, Reg must be 8 bits wide and Addr must be 21 bits wide on a revision 1.0 PCB or 23 bits wide on a revision 2.0 PCB. The external RAM will then be accessed as byte wide memory.

If you define 32 bit access to external memory using the PP1000_32BIT_RAMS preprocessor macro, Reg must be 32 bits wide and Addr must be 19 bits wide on a revision 1.0 PCB or 21 bits wide on a revision 2.0 PCB. The external RAM will then be accessed as 32 bit word wide memory.

You should not attempt to read or write twice from the same bank of memory in the same clock cycle.

PP1000ReadControl

PP1000ReadControl(Reg);

Arguments
Reg Register to receive the value from the control port. Must be 8 bits wide.
Return Values
Reg is set to the value from the control port.
Execution Time
Waits until data is written by host program.
Description

This macro procedure will read a byte from the control port. The control port can be written to by the PP1000WriteControl() function on the host. This macro procedure will wait until the host has written a value to the control port before completing. The host PP1000WriteControl() function will block until this macro procedure reads from the port.

This macro procedure should not be called in parallel with itself.

PP1000ReadGPO

PP1000ReadGPO();

Arguments
None
Return Values
Zero if GPO pin is low or one if GPO pin is high. Return value is one bit wide.
Execution Time
Zero clock cycles ( macro expression).
Description

This macro expression returns the value on the GPO pin. The value on this pin can be set by the host PP1000SetGPO() function.

PP1000ReleaseMemoryBank

PP1000ReleaseMemoryBank(Mask);

Arguments
Mask Mask of banks to release. Must be 4 bits wide.
Return Values
None.
Execution Time
One clock cycle.
Description

This macro procedure will release ownership of one or more memory banks.

Bit 0 (i.e. the LSB) of Mask should be set to 1 to release bank 0, bit 1 of Mask should be set to 1 to release bank 1 and so on.

This macro procedure should not be called in parallel with itself or with the PP1000RequestMemoryBank() macro procedure.

PP1000RequestMemoryBank

PP1000RequestMemoryBank(Mask);

Arguments
Mask Mask of banks request. Must be 4 bits wide.
Return Values
None.
Execution Time
Blocks until all banks are granted to the FPGA.
Description

This macro procedure will request ownership of one or more memory banks and wait until those banks are granted to the FPGA before returning.

Bit 0 (i.e. the LSB) of Mask should be set to 1 to request bank 0, bit 1 of Mask should be set to 1 to request bank 1 and so on. The requested bits are ORed with the current set of requested banks. Use the PP1000ReleaseMemoryBank() macro procedure to release ownership of memory banks.

This macro procedure should not be called in parallel with itself or with the PP1000ReleaseMemoryBank() macro procedure.

PP1000SetGPI

PP1000SetGPI(Expr);

Arguments
Expr Zero to clear GPI pin, non-zero to set GPI pin.
Return Values
None.
Execution Time
One clock cycle.
Description

This macro procedure will set the value of the GPI pin. The value on this pin can be read by the host PP1000ReadGPI() function.

This macro procedure should not be called in parallel with itself.

PP1000SetLEDs

PP1000SetLEDs(Mask);

Arguments
Mask Mask of LED states. Must be 8 bits wide.
Return Values
None.
Execution Time
One clock cycle.
Description

This macro procedure will set the state of all 8 LEDs in a single clock cycle. Bit 0 of Mask (i.e. the LSB) corresponds to LED 0, bit 1 of Mask corresponds to LED 1 and so on. When a bit is set to 1, the LED will be switched on and when set to zero the LED will be switched off.

This macro procedure should not be called in parallel with itself or with the PP1000LEDOn() or PP1000LEDOff() macro procedures.

PP1000WriteBank#

PP1000WriteBank0(Addr,Expr);
PP1000WriteBank1(Addr,Expr);
PP1000WriteBank2(Addr,Expr);
PP1000WriteBank3(Addr,Expr);

Arguments
Addr | Address to write data to. Must be 19, 21 or 23 bits wide.
Expr | Data to write to RAM. Must be 8 or 32 bits wide.
Return Values
None.
Execution Time
One clock cycle.
Description

These macro procedures should be used to write to the external memory banks on an RC1000-PP card. They can be used to access any banks in parallel but the memory banks must have been granted to the FPGA before an access is attempted. To request memory banks use the PP1000RequestMemoryBank() macro procedure.

If 8 bits access to memory is defined with the PP1000_8BIT_RAMS preprocessor macro, Expr must be 8 bits wide and Addr must be 21 bits wide on a revision 1.0 PCB or 23 bits wide on a revision 2.0 PCB. The external RAM will then be accessed as byte wide memory.

If 32 bits access to memory is defined with the PP1000_32BIT_RAMS preprocessor macro, Expr must be 32 bits wide and Addr must be 19 bits wide on a revision 1.0 PCB or 21 bits wide on a revision 2.0 PCB. The external RAM will then be accessed as 32 bit word wide memory.

You should not attempt to read or write twice from the same bank of memory in the same clock cycle.

PP1000WriteStatus

PP1000WriteStatus(Expr);

Arguments
Expr Expression to write to the status port. Must be 8 bits wide.
Return Values
None.
Execution Time
Waits till data is read by host program.
Description

This macro procedure will write a byte to the status port. The status port can be read with the PP1000ReadStatus() function on the host. This macro procedure will wait until the host has read the data from the control port before completing. The host PP1000ReadStatus() function will block until this macro procedure writes to the port.

This macro procedure should not be called in parallel with itself.


 Disclaimer

Reasonable endeavors have been made to ensure that material contained on this web site(1) was correct at the time the page was created and last modified. No warranty is given and no responsibility will be taken for the accuracy or the completeness of the material.

No reliance should be made by any user on the material, but instead the user should check for confirmation with the originating or authorizing faculty, department or other body.

Should queries to any text or declarations in these pages arise, the user should refer to the original source documentation(2), contact Embedded Solutions Ltd or visit the Embedded Solutions website.

Changes may be made at any time, when deemed appropriate.

(1) The web site here refers to the files, HHelp_html_version.htm and RC1000Help_htmlversion.htm and any files linked from them not including domains external from its source.

(2) The source documentation referred to are the PDF documentation released with then Handel-C and RC1000-PP drivers installations: swref.pdf, fnref.pdf, hwref.pdf, langref.pdf, compref.pdf, cppref.pdf.


Handel, George Frideric

1685 ~ 1759

Handel was one of the greatest composers of the late baroque period and, during his lifetime, perhaps the most internationally famous of musicians. Handel was born February 24, 1685, in Halle, to a family of no musical distinction. His own musical talent, however, manifested itself so clearly that before his tenth birthday he began to receive from a local organist the only formal musical instruction he would ever have.

Throughout his life Handel avoided the rigorous contrapuntal techniques of his compatriot and exact contemporary Johann Sebastian Bach and achieved his effects through the simplest of means, trusting always his own innate musicianship. Handel's legacy lies in the dramatic power and lyrical beauty inherent in all his music. Handel's greatest gift to posterity was undoubtedly the creation of the dramatic oratorio genre, partly out of existing operatic traditions and partly by force of his own musical imagination.

Although today, as in the 19th century, Handel is best known for only a few of his works, such as Water Music and Messiah, more and more attempts are being made to bring his other compositions, especially his operas, to the public acquaintance. Handel's rich and unique musical genius deserves to be remembered in the extraordinary fullness of its entirety.

Tribute to Handel

Concerti Grossi Op.6,
No.8 in C - Allemande

Water Music,
Suite No.2 in D - Alla Hornpipe

Messiah,
Hallelujah Chorus


RC1000-PP type declarations

Type definitions to support the RC1000-PP

Types usable by host programs

All the types included below are defined in the header file, pp1000.h, supplied by Embedded Solutions Ltd.

Masks for memory bank request and grant lines

#define PP1000_RAM_REQ0 (1<<0)
#define PP1000_RAM_REQ1 (1<<1)
#define PP1000_RAM_REQ2 (1<<2)
#define PP1000_RAM_REQ3 (1<<3)
#define PP1000_RAM_GNT0 (1<<4)
#define PP1000_RAM_GNT1 (1<<5)
#define PP1000_RAM_GNT2 (1<<6)
#define PP1000_RAM_GNT3 (1<<7)

PP1000_CARD_INFO

/*
 * Card information structure
 */

typedef struct
{
PP1000_DEVICE_NUM CardID;
unsigned long PMC1Fitted;
unsigned long PMC2Fitted;
unsigned long RAMBankFitted[4];
unsigned long RAMBankSpace[4];
PP1000_FPGA_TYPE FPGAType;
unsigned long PhysicalMemoryBase;
unsigned long *MemoryBase;
unsigned long BoardRevision;
unsigned long LogicRevision;
unsigned long SerialNum;
unsigned long Timeout;
} PP1000_CARD_INFO;

PP1000_CHANNEL

/*
 * DMA channel handle
 */

typedef void *PP1000_CHANNEL;

PP1000_CLOCK

/*
 * Clock selections
 */

typedef enum
{
PP1000_MCLK,
PP1000_VCLK
} PP1000_CLOCK;

PP1000_DEVICE_COUNT

/*
 * Structure for counting number of cards
 */

typedef struct
{
PP1000_DEVICE_NUM CardID;
unsigned long Count;
} PP1000_DEVICE_COUNT;

PP1000_DEVICE_NUM

/*
 * A value to indicate which card
 */

typedef unsigned long PP1000_DEVICE_NUM;

PP1000_DMA_DIRECTION

/*
 * DMA direction options
 */

typedef enum
{
PP1000_PCI2LOCAL,
PP1000_LOCAL2PCI
} PP1000_DMA_DIRECTION;

PP1000_FPGA_TYPE

/*
 * FPGA Type
 */

typedef enum
{
PP1000_FPGA_4085XL,
PP1000_FPGA_40150XV,
PP1000_FPGA_40200XV,
PP1000_FPGA_40250XV,
PP1000_FPGA_V1000,
PP1000_FPGA_UNKNOWN
} PP1000_FPGA_TYPE;

PP1000_HANDLE

/*
 * Handle of a card
 */

typedef void *PP1000_HANDLE;

PP1000_HANDLER_FUNCTION

/*
 * Error handler function type
 */

typedef void (*PP1000_HANDLER_FUNCTION)(char *FnName, PP1000_STATUS Status);

PP1000_IS_ERROR

#define PP1000_IS_ERROR(Status) ((Status) >= PP1000_STATUS_ERROR_CODE)

PP1000_MEMORY_SPACE

/*
 * DMA memory space options
 */

typedef enum
{
PP1000_VIRTUAL,
PP1000_PHYSICAL
} PP1000_MEMORY_SPACE;

PP1000_STATUS

/*
 * Status and error codes
*/

typedef enum {
  PP1000_SUCCESS = 0,
  PP1000_NO_DRIVER = PP1000_STATUS_ERROR_CODE,
  PP1000_INTERNAL_ERROR,
  PP1000_NO_MEMORY,
  PP1000_NULL_POINTER,
  PP1000_INVALID_CARDID,
  PP1000_NO_FREE_CARDS,
  PP1000_INVALID_HANDLE,
  PP1000_FILE_NOT_FOUND,
  PP1000_FILE_ACCESS_ERROR,
  PP1000_INVALID_FILE,
  PP1000_INVALID_PART_TYPE,
  PP1000_INVALID_CLOCK_RATE,
  PP1000_FPGA_MISMATCH,
  PP1000_INVALID_IMAGE,
  PP1000_TIMEOUT,
  PP1000_INVALID_CLOCK,
  PP1000_CARD_BUSY,
  PP1000_INVALID_ALIGNMENT,
  PP1000_INVALID_ADDRESS_SPACE,
  PP1000_INVALID_DIRECTION,
  PP1000_INVALID_CHANNEL,
  PP1000_LOCK_FAILED,
  PP1000_INVALID_ARGUMENT,
  PP1000_CANCELLED
} PP1000_STATUS;

PP1000_IMAGE

/*
 * FPGA Image file
 */

typedef void * PP1000_IMAGE;

PP1000_TIMEOUT_INFINITE

/*
 * Infinite timeout length
 */

#define PP1000_TIMEOUT_INFINITE 0xffffffff