\input texinfo    @c -*-texinfo-*-
%
% doc.cxdrv - main file for the documentation
%
% Copyright (C) 1995   rubini@ipvvis.unipv.it (Alessandro Rubini)
%
%%%%

%------------------------------------------------------------------------------
%
%                         NOTE FOR THE UNAWARE USER
%                         =========================
%
%    This file is a texinfo source. It isn't the binary file of some strange
%    editor  of mine. If you want ascii, you should "make cxdrvdoc.txt".
%
%------------------------------------------------------------------------------

%
% This is not a conventional info file...
% I use two extra features:
%       - The '%' as a comment marker ("\%" -> "%")
%       - leading blanks are allowed (and removed)
%

@comment %**start of header
@setfilename cxdrv.info
@settitle Linux driver for the cx100 frame grabber, version @value{version}
@iftex
@afourpaper
@end iftex
@comment %**end of header

@syncodeindex tp fn
@syncodeindex vr fn

@ignore
@ifinfo
@format
START-INFO-DIR-ENTRY
* cx100 driver: (cxdrv.info).      A Linux-1.2 module for the cx100 grabber
END-INFO-DIR-ENTRY
@end format
@end ifinfo
@end ignore

@setchapternewpage off

@set version 0.85    %RELEASE
@set update-month October 1995

@c allow changing the predefined style
@tex
\input localstyle.tex
@end tex

@finalout

@ifinfo
This file is the user's and programmer's manual for cxdrv @value{version}.

Copyright (C) 1995 Alessandro Rubini

Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
are preserved on all copies.

@ignore
Permission is granted to process this file through TeX and print the
results, provided the printed document carries copying permission
notice identical to this one except for the removal of this paragraph
(this paragraph not being relevant to the printed manual).

@end ignore
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided that the entire
resulting derived work is distributed under the terms of a permission
notice identical to this one.

Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions,
except that this permission notice may be stated in a translation approved
by the Free Software Foundation.
@end ifinfo

@setchapternewpage odd
@titlepage
@c use the new format for titles
@title cx100 device driver @value{version}
@subtitle A modularized driver for the cx100 frame grabber
@subtitle @value{update-month}

@author by Alessandro Rubini (@code{rubini@@ipvvis.unipv.it})

@end titlepage
@setchapternewpage off
@headings single

@ifinfo
This file documents the @value{version} release of the @code{cxdrv} 
module for Linux-1.2 and later (@value{update-month}).

@node Top, Overview, (dir), (dir)
@top cxdrv

@menu
* Overview::                    
* Compiling and Installing::    
* The driver::                  
* The Library::                 
* The Dos-Compatible Library::  
* The Sample Programs::         
* Function Index::              
@end menu

@end ifinfo

%##########################################################################
%##########################################################################
@node Overview, Compiling and Installing, Top, Top
@chapter Overview
@cindex Overview

The device driver for the cx100 frame grabber is designed as a dynamically
loadable module for the Linux kernel. The distribution encloses the device
proper, a library of useful functions and a few sample programs using
the grabber.

The device driver implements @t{open}, @t{close}, @t{read}, @t{write},
@t{ioctl} and @t{select}. The current design allows for up to 8 cx100
boards, however, I've only one, and couldn't test with more of them.

The library is meant to be a slight help to the programmer. It offers
access to @t{ioctl()} calls at a higher level of abstraction.

The dos-compatible library is a @i{deprecated} entity. It offers the
same unstructured function calls offered by the dos library distributed
by ImageNation. Existing dos programs should compile and with little or no
problems by linking with ``@t{-l libcxgdos}.

The sample programs, then, are what I used to test the device driver, and
are enclosed in the distribution to ease your own testing and to be copied
by the programmers.


%##########################################################################
@node Compiling and Installing, The driver, Overview, Top
@chapter Compiling and Installing

A simple  "@t{make}" invocation will compile the  module, the  libraries and
the test programs. A "@t{make install}" will install  things in the proper
places.

The default ``prefix'' is @file{/usr/local}, so installed files will go
into @file{/usr/local/bin}, @file{/usr/local/lib} and so on. To change
the prefix (and use, for example, @file{/usr}), you should specify
"@t{PREFIX=/usr}" on the @t{make} command line, both when compiling and
when installing.

The module is installed in @file{/lib/modules/@i{version}/misc},
where @i{version} is your current Linux version.

%=========================================================================
@menu
* Loading and Unloading::       
@end menu

@node Loading and Unloading,  , Compiling and Installing, Compiling and Installing
@section Loading and Unloading the Module
@cindex load
@cindex insmod
@cindex unload
@cindex rmmod

To load the module the user should issue "@t{./cxg_load}" in the distribution
directory. The script  is a  simple wrapper
around "@t{insmod}", which  creates the  /dev  nodes after   loading  the
module. Execution of the script needs superuser privileges.

To unload the module, "@t{./cxg_unload}" is provided. The script is a wrapper
around "@t{rmmod}" which additionally removes the @file{/dev} nodes.

There are a few public variables in the module which can be modified at
load time. Integer values may be assigned to them on the command line of
@t{cxg_load}, because the whole commandline is passed along to @t{insmod}.

@table @code
@item cxg_base
        Setting this variable (0 by default) disables autodetection of
        the board and forces an I/O base address. Since only one base
        address can be specified, multiple boards can only be reached
        via autodetection (the preferred way anyways).

@item cxg_major
        This variable (0 by default) assigns a major device number to the
        driver, disabling dynamic assignment. You can use this variable if
        you don't want to create and destroy device nodes when
        loading/unloading the module. You should remember that major number
        in the range 1-31 are already assigned, and dynamic numbers start
        from 63 and grow downwards.

@item cxg_fake
        Enables loading the driver even when no board is there.
        If one board is there and you set @t{cxg_fake} to 1 you'll
        see two boards: one working and one not. for performance issues,
        a fake board can be used only if the package is compiled with
        @t{DEBUG_CX100} turned on; otherwise any @t{open()} call issued
        on a fake board will fail.

@item cxg_ram
        Only for the first board, choose the ram page to be used for the
        grabber memory. Be careful about this, since no check is performed
        about actual segment availability. For additional boards, the ram
        page can only be set using @t{Cxg_RamPage}. @xref{Setting Modes}.
        The function is the preferred way anyways, since it can autodetect
        a free memory segment.

@item cxg_irq
        Only for the first board, choose the irq line to be requested.
        For additional boards, the irq line can only be requested using
        @t{Cxg_SetIrq}. @xref{Setting Modes}.

@end table

As an exmaple, the following command line could work (

@lisp
        ./cxg_load   cxg_ram=10 cxg_fake=1
@end lisp

%##########################################################################
@node The driver, The Library, Compiling and Installing, Top
@chapter The Driver Proper

%MANPAGE cxdrv.4
%M .TH CXDRV 4 "October 1995"
%M .UC 4
%M .SH NAME
%M /dev/cxg* - CX100 Grabber boards, as a kernel module, called `cxdrv'.
%M .SH DESCRIPTION
%M The module allows user program to use the frame grabber boards quite
%M effeciently, by implementing the standard device entry points.
%M
%M The information below is extracted from the texinfo file, which is the
%M preferred source of information.

The driver is able to manage up to eight frame grabber boards (though it
has only been tested with one board). The implemented functions are
@t{open()}, @t{close()}, @t{read()}, @t{write()}, @t{seek()},
@t{ioctl()} and @t{select()}. @t{mmap()} is not implemented due to
laziness on my side.

Each board can be opened multiple times. Multiple opens share some board
features, which are hardware-related (for example being low/high
resolution), while other features are private to each open file.

In particular, the user can specify a set of ``Regions of Interes'' (ROI's)
private to each file. When reading the file, then, only the specified
regions are returned, either as raw data or as a @t{pgm} image. @xref{ROIs}.

Each open file can also specify how frequently data must be gathered, in
order to achieve blocking read. This option however is currently only
supported for the raw (whole frame at a time) device.

Different @t{/dev} nodes are created for each recognized board, to accomplish
different tasks

@menu
* The /dev Nodes::              
* Open and Close::              
* Read::                        
* Write::                       
* Ioctl::                       
* Select::                      
* ROIs::                        
@end menu

%=========================================================================
@node The /dev Nodes, Open and Close, The driver, The driver
@section The @t{/dev} Nodes

%M .SH DEVICE NODES

Each frame-grabber board existing in the system is accessed by means of
three different file-system nodes. 

@table @code
@item /dev/cxg0
        `Cx100 grabber' 0. This is the raw device. It can always be opened
        when a board exists in the computer. Diagnostics can be performed
        on the board, but any "real work" that requires memory mapping or
        interrupt reporting needs @t{ioctl()} invocation to ebable either
        feature. Blocking read is allowed on this device if the board
        generates interrupts.

@item /dev/cxg0ol
        The overlay device. If your board supports overlays, this device
        can be read-from or written-to just like @t{/dev/cxg0}. R/w
        operations will affect overlay memory instead of frame memory.
        Not tested as of 0.85

@item /dev/cxg0f
        Full-featured device. @t{open()} will succeed only if both
        memory-mapping and the interrupt can be detected. The first @t{open()}
        invocation may take up to 1 seconds to succeed (or fail), due to
        interrupt probing. Successive @t{open()}s will be faster because
        the probed irq number is retained. This device allows blocking
        read and selecting.

@item /dev/cxg0pgm
        Simple pgm device. Its opening enables memory mapping
        and continuous grabbing. This means that the device can be used as
        a simple live video. A pgm header is added to each frame. Use of
        this node can't coexist with use of other nodes, because there is
        one video memory for each board. Writing to this file changes the
        size and position of the pgm image being returned. Blocking read
        is not allowed here, not select(), due to my lazyness.

@end table

Note however that board features like memory mapping and irq reporting are
global. Thus, enabling/disabling them on one device will enable/disable
for all of them.

The second board is accessed through nodes @t{/dev/cxg1}@i{xx}, and so on,
up to @t{/dev/cxg7}@i{xx}.

Please note that boards older than at least October 1995 are not able to
generate interrupts when driven by a PAL (european) camera. This is a
very infortunate bug in the board (interrupts *are* useful under a real
operating system), and ImageNation promised to fix the board microcode
as soon as possible.

%=========================================================================
@node Open and Close, Read, The /dev Nodes, The driver
@section Open and Close
@cindex open()
@cindex close()

%M .SH OPEN AND CLOSE

The minor device number of the device node is used to identify which device
is being accessed and in what way. A single board has multiple personality.
@xref{The /dev Nodes}.

On open, a structure to hold file-specific information is allocated, and
it exists up to file closing. No check regarding hardware features
is ever performed. Thus, when the device is opened multiple times, you
must be careful to run cooperating processes.

Correct file permissions on the nodes should be used to enforce authorized
use.

On the first @t{open()}, the board is powered up, and a small delay is
performed to ensure everything is setup for correct workings. On the
last @t{close()} the board is powered down, and any existing irq or memory
mapping is released. If you want to keep a persistent board state across
program execution, you need to keep the device open at least once.
A stopped @t{cat /dev/cxg0 > /dev/null} or anything else will work fine.
I use @t{./test P t1 L} ("print the board ports, timeout one second and
loop over").

%=========================================================================
@node Read, Write, Open and Close, The driver
@section Read
@cindex read()

%M .SH READ

When the device is read, data is returned according to the current
configuration of the file being read. The configuration mode can be set
using @t{Cxg_SetRoi()} and @t{Cxg_PgmMode}. @xref{Setting Modes}.
Note that before reading the device, you have to specify which segment
in the computer memory is to be mapped by the device (through
@t{Cxg_RamPage}. If no memory segment is being used, then @t{read()}
will return 0 (to signal no data was there). The ram page is automatically
allocated for `full' devices.

The @t{read()} invocation may be blocking, if a grabbing interval
was specified through @t{Cxg_SetStep()}. @t{read()} will block only in
raw mode. Guess why: lazyness.
% in the future: "whichever mode is being used. @xref{Intervals}."
%M See below about setting intervals.

@cindex modes

@menu
* Raw Mode::                    
* RoI Mode::                    
* Pgm Mode::                    
@end menu


%-------------------------------------------------------------------------
@node Raw Mode, RoI Mode, Read, Read
@subsection Raw Mode
@cindex raw mode

%M .SS RAW READ

Right after opening, the file is in ``raw'' mode, and data being returned
is the whole video memory. If the physical device is in high resolution,
then @t{read()} Will return the same pixel after 256kb. If the device
is in low resolution, the same pixel will be returned after 64kb.

``Raw'' mode used to be the worst of all modes -- data is returned
without performing any control on the current video page.

If you have interrupts and blocking-read, however, raw mode may be useful
to read whole frames on a timely basis.  @xref{Scheduling Acquisition}.

%-------------------------------------------------------------------------
@node RoI Mode, Pgm Mode, Raw Mode, Read
@subsection RoI Mode
@cindex roi mode

%M .SS ROI READ

After  you invoke @t{Cxg_SetRoi()} with a non-null argument, the
drivers goes in roi mode. Data returned from @t{read()} will only
be the content of the selected regions of interest.

This allows for fast grabbing of sequences in case you're only
interested in a small part of the whole frame. The program can run in 
a tight loop of @t{read()}, without the need to care
for regions after setup. Using rois is faster than selecting
parts after transferring to memory the whole frame, because the transfer
through the PC bus is the slowest part of all the process.

Region xfer is another way to transfer subareas of a frame. However,
region transfer is not blocking.

%-------------------------------------------------------------------------
@node Pgm Mode,  , RoI Mode, Read
@subsection Pgm Mode
@cindex pgm mode

%M .SS PGM READ

Sometimes it's useful to directly read pgm's from the device, instead of
unstructured raw data. The pgm mode of the driver is only available when
RoI's are enabled. @ref{RoI Mode}.

To enable/dibable pgm mode you need to @t{Cxg_PgmMode()}. Subsequent
@t{read()s} from the device will return the pgm header before the pixel data
of each RoIs. Raw mode doesn't allow putting a pgm header in from of the
frame.

Reading the @t{/dev/cxg0pgm} (or equivalent), instead, returns a single pgm
image on each open. This operation is not blocking, as of 0.85.

%=========================================================================
@node Write, Ioctl, Read, The driver
@section Write
@cindex write()

%M .SH WRITE

Write is not available as of 0.85 (But it will be soon).

%=========================================================================
@node Ioctl, Select, Write, The driver
@section Ioctl
@cindex ioctl()

%M .SH IOCTL

The @t{ioctl()} call is implemented to perform all the non-read and
non-write operations.

Several ioctl commands are available, but rather than documenting them
here, I'd better talk about library funcitions (macros) to access such
functionality on an higher level. @xref{The Library}.
%M The library is documented in cxg(3).

Note that cx100 command numbers and bit numbers are available as
symbolic entities, defined in @file{"cxdrv.h"}.


%=========================================================================
@node Select, ROIs, Ioctl, The driver
@section Select
@cindex select()

%M .SH SELECT

The select call is only meaningful if you have enabled interrupts on
your board (if you use the `full' device, interrupts are enabled at
@t{open()} time). If no interrupts are there, the @t{read()} call will
not block, and @t{select()} will always report the file as readable.

The `overlay' device (if any) is always readable.

Select for writing, on the other hand, will always tell that the
device is writable, because you are always allowed to overwrite video or
overlay memory.

%M .SH MMAP

The other esotheric file interface, @t{mmap()}, is not implemented.
Mainly because I don't need it, and I'm not paid to write it ;-)

%=========================================================================
@node ROIs,  , Select, The driver
@section Regions of Interest
@cindex ROIs

.SH USING REGIONS OF INTEREST

A ``Region of Interest'' is a rectangle in the video memory. Using regions
of interest instead of transferring the whole frame in conventional RAM
can reduce bus overhead (being an ISA card is the weak point of the cx100
grabber).

You can exploit regions of interest by either @t{read()ing} only the
interesting part of video memory or by transferring a single region or
regions on specific @t{ioctl()} requests. The @t{read()} approach is
preferred, because you can instruct the driver to read image data
every so-many frames.

To configure @t{read()}, you should invoke @t{Cxg_SetRoi} before
tha actual @t{read()} calls. Successive reads will cycle through the
Regions specified. To transfer specific regions you should invoke
@t{Cxg_XferRegion}. Details about @t{Cxg_Roi} are under the library docs.
@xref{Setting Modes}.

% man-page footer
@ignore
.SH AUTHOR
.nf
Alessandro Rubini <rubini@ipvvis.unipv.it>, or <rubini@systemy.it>
.fi

.SH FILES
.nf
/dev/cxg0       Raw frame grabber
/dev/cxg0f      Full grabber (rampage and interrupts)
/dev/cxg0ol     Overlay memory, if available
/dev/cxg0pgm    Pgm images.
/dev/cxg1...    Second board, if any.
.fi

.SH SEE ALSO
.nf
cxdrv(3)      The library functions to access ioctl().
cxdrv(1)      Installed executables related to the cx100.
.fi
The info file about `cxdrv', a superset of the man pages.
@end ignore
%MANPAGE END


%##########################################################################
@node The Library, The Dos-Compatible Library, The driver, Top
@chapter The Support Library

%MANPAGE cxdrv.3
%M .TH CXDRV 3 "October 1995"
%M .SH NAME
%M .nf
%M #include <cxdrv.h>
%M Cxg_*(...)
%M .fi
%M The user-level functions used to access the cx100 frame-grabber board.
%M
%M .SH DESCRIPTION

The main role of the support library is to provide well-named functions
to access ioctl functionality. In the following description,
the @var{fd} argument must always be the
file descriptor associated to the frame grabber.

The library functions are often implemented as macros, but this is not
documented. It doesn't make difference to you, unless you try to take
the function's address (unlikely).

The functions never modify their arguments, even when they are macros.

All the functions return -1 in case of error (setting @t{errno} to
a meaningful value), and 0 or the requested value ( >= 0 ) in
case of success.

When the macro implementation evaluates its arguemnts more than once,
this misfeature is documented.

Symbols for bit values and commands are defined in @t{cxdrv.h}, which
must be included in your source. The symbols are different from those
released bt ImageNation, because I try to keep a clean namespace. Symbols
are not described here, because I'm lazy (keep a copy of @t{cxdrv.h} handy
to cut and paste what you need).

@menu
* Bit Manipulation::            
* Command::                     
* Information Retrivial::       
* Grab Control::                
* Setting Modes::               
* Field Counter::               
* Delays::                      
* Region Transfer::             
* Scheduling Acquisition::      
@end menu

%---------------------------------------------------------------------------
@node Bit Manipulation, Command, The Library, The Library
@section Bit Manipulation

%M .SH BIT MANIPULATION

@deftypefun int Cxg_GetPorts (int @var{fd}, char *@var{where});
        Returns the status ports.
        @var{where} is a pointer to an array
        of four characters. On return, these characters will embed the
        current value of the four status ports (ports 0, 1, 2, 6)
        of the frame grabber.
@end deftypefun

@deftypefun int Cxg_SetBit (int *@var{fd}, int @var{bit});
@deftypefunx int Cxg_ClrBit (int *@var{fd}, int @var{bit});
        Turn on/off a single bit. The bit number is checked for overflow.
@end deftypefun

@deftypefun int Cxg_SetBitV (int *@var{fd}, int @var{bit}, int @var{v});
        Sets one bit to a particular value. The @var{v} value must be
        zero or not-zero. The bit number is checked for overflow.
@end deftypefun

@deftypefun int Cxg_GetBit (int *@var{fd}, int @var{bit});
        Return the current value of the bit (zero or not-zero).
        Turn on/off a single bit. Note that @t{Cxg_GetPorts} is faster if
        you need to look to more than one bit.
        The bit number is checked for overflow.
@end deftypefun

@deftypefun int Cxg_SetPage (int *@var{fd}, int @var{page});
        Sets the current memory page of the grabber. This call is not
        needed (it's dangerous) unless you're grabbing in low resolution.
        In this case it sets the current image. This macro evaluates twice the
        @var{page} argument (of which only the lowest two bits are used).
@end deftypefun

%---------------------------------------------------------------------------
@node Command, Information Retrivial, Bit Manipulation, The Library
@section Command

%M .SH CX COMMAND

@deftypefun int Cxg_Command (int @var{fd}, int @var{cmd});
        Invoke a cx100 command.
        This specified  hardware command @var{cmd} is invoked on the
        board. The result is an 8-bit value. The command number is not
        checked for ranges.
@end deftypefun

%---------------------------------------------------------------------------
@node Information Retrivial, Grab Control, Command, The Library
@section Information Retrivial

%M .SH INFORMATION RETRIVIAL

@deftypefun int Cxg_GetHwInfo (int @var{fd}, Cxg_Board *@var{ptr});
        This call fills a structure in user space. The structure is
        defined in @t{<cxdrv.h>}. Fields in the structure are the
        same for different file descriptors referring to the same board.
@end deftypefun

@deftypefun int Cxg_GetSwInfo (int @var{fd}, Cxg_Clientdata *@var{ptr});
        This call fills a structure in user space. The structure is
        defined in @t{<cxdrv.h>}. Fields in the structure are different
        for different file descriptors. This call is only interesting for
        debugging the driver itself.
@end deftypefun

@deftypefun int Cxg_GetRamInfo (int @var{fd}, char *@var{ptr});
        Fills a 16 byte wide array with values telling if the ram
        segment contains ram, rom, another cx100 board or if it is
        empty. Symbolic names for the values are defined in @t{<cxdrv.h>}.
@end deftypefun

@deftypefun int Cxg_LibVersion (void);
        This macro returns a string describing the version of the library.
        Actually, this is a constant value taken from the header.
        Obviously you must keep the header and the library in sync.
@end deftypefun

%---------------------------------------------------------------------------
@node Grab Control, Setting Modes, Information Retrivial, The Library
@section Grab Control

%M .SH GRAB CONTROL

These functions are used to control grabbing. The @var{wflag} argument
tells if the call must wait for acquisition to complete (not-zero) ore
return right after requesting acquisition (zero). If no video is there
the functions set @t{errno} to @t{ENODATA}.

@deftypefun int Cxg_GrabFrame (int @var{fd}, int @var{wflag});
        Requests grabbing of one frame at the beginning of the next vertical
        blank. If the board is in low resolution, only one field will be
        grabbed.
@end deftypefun

@deftypefun int Cxg_GrabField (int @var{fd}, int @var{wflag});
        Requests grabbing of one field at the beginning of the next vertical
        blank.
@end deftypefun

@deftypefun int Cxg_GrabFieldN (int @var{fd}, int @var{n}, int @var{wflag});
        Requests grabbing of a specific field (wait for one or two blankings.
@end deftypefun

@deftypefun int Cxg_GrabLive (int @var{fd});
        Turns on continuous acquisition.
@end deftypefun

@deftypefun int Cxg_GrabOff (int @var{fd});
        Turns off continuous acquisition.
@end deftypefun

%---------------------------------------------------------------------------
@node Setting Modes, Field Counter, Grab Control, The Library
@section Setting Modes

%M .SH SETTING MODES

@deftypefun int Cxg_SetIrq (int @var{fd}, int @var{irq});
        Enable the frame grabber to use interrupts.
        The extra argument is the interrupt number to request. If
        an irq line is already active, it is released beforehand.
        The special values @t{CXG_AUTODETECT} and @t{CXG_IRQ_NONE}
        are used to try to autodetect the irq line and to release any
        active line. Autodetection is @i{really} tentative, because the
        board is not equipped for autodetection.
        @b{This doesn't work at time of writing}.
@end deftypefun

@deftypefun int Cxg_RamPage (int @var{fd}, int @var{arg});
        Tell the device to use a particular ram page to map the video
        memory. The @var{arg} argument should be a number in the range 0xA-0xF.
        Zero means ``no change'', -1 means ``disable mapping''.
        @t{CXG_AUTODETECT} works well. Any another
        value will cause @t{EINVAL} to be issued.
        The return value is the page number where the video memory gets
        actually mapped.
@end deftypefun

@deftypefun int Cxg_SetRoi (int @var{fd}, Cxg_Roi *@var{roi});
        Configures the driver to return only the selected regions
        on interest at the following @t{read()} calls. @xref{Read}.
        If @var{roi} is @t{NULL} normal raw reading will be performed.
        The @var{roi} pointer must point to an array of @t{Cxg_Roi}
        structure, and the field @t{count} of the first region in the
        array tells how many regions are there. the fields @t{x}, @t{y},
        @t{wid}, and @t{hei} are used to identify the rectangular region.
@end deftypefun

@deftypefun int Cxg_LowRes (int @var{fd}, int @var{flag});
        Puts the board in
        low or high resolution according to the argument (0 or not 0).
        This is more than setting the low-resolution bit on the board
        ports. Note that when the board is in low resolution you are free
        to choose which page to use, through @t{Cxg_SetPage}.
@end deftypefun

@deftypefun int Cxg_PgmMode (int @var{fd}, int @var{flag})
        Enables or disables the generation of pgm (Portable GrayMap) output
        when in Roi mode. @xref{ROIs}. The extra argument is 0 or 1 to
        disable/enable pgm generation. Pgm generation is disabled by default.
        If you need pgm frames as standalone foles, use @t{/dev/cxg0pgm}
        instead of the raw device.
@end deftypefun


%---------------------------------------------------------------------------
@node Field Counter, Delays, Setting Modes, The Library
@section Field Counter

%M .SH THE FIELD COUNTER

Note that the field counter in this driver is a 32 bits value, even if
the board only has a 16 bits counter. This is needed when long-running
application must schedule time-delayed acquisitions (a 16 bit value makes
one complete round in more or less 20 minutes).

@deftypefun int Cxg_ClearFC (int @var{fd})
        Clears the field counter.
@end deftypefun

@deftypefun unsigned Cxg_GetFC (int @var{fd});
        Returns the current field counter. The -1 value is quite
        unlikely to happen because it would happen after 1 thousand days
        continuous acquisition.
@end deftypefun

%---------------------------------------------------------------------------
@node Delays, Region Transfer, Field Counter, The Library
@section Delays

%M .SH DELAYS

@deftypefun int Cxg_WaitVb (int @var{fd});
        Wait till the next vertical blank.
@end deftypefun


@deftypefun int Cxg_WaitVbField (int @var{fd}, int @var{field});
        Wait till the next vertical blank corresponding to a specific field.
@end deftypefun

@deftypefun unsigned Cxg_WaitTillCount (int @var{fd}, int @var{count});
        Wait till the field counter reaches the specified @var{count}.
        If that current count is already over, return straight ahead.
        The return value is the current value of the field counter
        (this means that if all is ok, it should be equal to @var{count}).
        This time delay is not a busy loop: normal CPU scheduling can
        go on during latency. If I could get interrupts, however, it could
        be much easier to implement and even less requiring for the CPU.
@end deftypefun

%---------------------------------------------------------------------------
@node Region Transfer, Scheduling Acquisition, Delays, The Library
@section Region Transfer

%M .SH REGION TRANSFER

@deftypefun int Cxg_GetRegion (int @var{fd}, Cxg_Roi *@var{ptr});
@deftypefunx int Cxg_PutRegion (int @var{fd}, Cxg_Roi *@var{ptr});
        These two functions perform atomic region transfer from the
        grabber memory to computer ram, and vice-versa.
        The Roi argument pointed to by @var{ptr} must feature valid
        @t{wid}, @t{hei}, @t{x}, @t{y}, and @t{count} fields.
        @t{count} should be set to 1, in case future releases of
        the driver will support transferring an array of regions.
        The field @t{xtra.data} must point to a valid memory region,
        where data to be transferred is found/put.

        The transfer will either succeed or fail -- half transfers will
        never happen. Note that this call works with either conventional
        memory or overlay memory, according to the device node being used.

@end deftypefun


%---------------------------------------------------------------------------
@node Scheduling Acquisition,  , Region Transfer, The Library
@section Scheduling Acquisition

%M .SH SCHEDULING ACQUISITION

@deftypefun int Cxg_Interval (int @var{fd}, int @var{step}, int @var{next});
@deftypefunx int Cxg_SetStep (int @var{fd}, int @var{step});
@deftypefunx int Cxg_SetNext (int @var{fd}, int @var{next});
        Each open file related to the driver can set its own scheduling
        policy. The scheduling policy is made up of an interval (number of
        frames between successive grabbings) and a next-frame (which frame
        is to be grabbed next time). Usually setting the step is sufficient,
        because the next frame is automatically set to the very-next frame
        returned from the camera. Please be careful as only @t{SetStep()}
        has been actually used, and it only works if your hardware is capable
        of generating interrupts. Enhancements on blocking-read issues are
        expected quite soon.
@end deftypefun

Note that these calls don't return any video data. They only tell the
driver to act in blocking mode. Any subsequent read will block till the field
counter reaches the right value and then grab one frame/field before returning
data. Support for @t{O_NONBLOCK} is  provided.

%If interrupts are available on your system, @t{select()} may be used.
%Since I live in Europe and PAL cameras can't generate interrupts on
%current cx100 boards (bug, not feature) I may provide support for select
%using interval timers -- not available at time of writing these docs.


% man-page footer
@ignore
.SH AUTHOR
.nf
Alessandro Rubini <rubini@ipvvis.unipv.it>, or <rubini@sytemy.it>
.fi

.SH FILES
.nf
/dev/cxg0       Raw frame grabber
/dev/cxg0f      Full grabber (rampage and interrupts)
/dev/cxg0ol     Overlay memory, if available
/dev/cxg1...    Second board, if any.
.fi

.SH SEE ALSO
.nf
cxdrv(4)      The device proper.
cxdrv(1)      Installed executables related to the cx100.
.fi
The info file about `cxdrv', a superset of the man pages.
@end ignore
%MANPAGE END

%##########################################################################
@node The Dos-Compatible Library, The Sample Programs, The Library, Top
@chapter The Dos-Compatible Library

The dos compatibility library is meant to ease porting of programs
written for dos to the Linux operating system. Note however that most
of the features described below are untested. Moreover, work in this
direction is very slow, because I write my own programs using the
@t{Cxg_} functions. Feel free to report any problem to me.

To use the compatibility library, you should link your program with
``@t{-lcxdrvdos}'', and include @t{<cx100.h>} from your source file.

%##########################################################################
@menu
* Dos-compatible Variables::    
* Dos-compatible Functions::    
@end menu

@node Dos-compatible Variables, Dos-compatible Functions, The Dos-Compatible Library, The Dos-Compatible Library
@section Dos-compatible Variables

The following table lists all the global variables documented in the
Software Manual from ImageNation (in the same order),
and reports their status in the
compatibility library.

@table @code
@item fg
        The variable is not supported, by now. 
@item FGDATA Fd[MAX_PORTS]
        The array is filled by @t{init_library()}, though it is a
        fictious entity: not all fields in the structure make sense.
        @table @code
        @item cx
                @t{TRUE} ot @t{FALSE}
        @item fgp
                Not set nor useable
        @item addr
                Not set not useable
        @item video
                @t{TRUE} or @t{FALSE}
        @item ccir
                @t{NTSC} or @t{CCIR}
        @item rev
                Revision number
        @item off
                Power-off
        @end table

@item SEGDATA Sd[MAX_SEGS]
@itemx int pc_display
@itemx BYTE far *videoram
@itemx WORD video_seg
        These variables/arrays aren't  supported, and won't ever be.
        Memory management in performed in the driver, and users don't
        need such information. The structure @t{SEGDATA} is not defined,
        either.

@item int lastrow
        This works are documented.
@item int x_char
@item int y_char
        No text drawing capability is there, by now.
@item int port_bits[31][2]
        Not existent. You shouldn't use it anyways.
@end table

%##########################################################################
@node Dos-compatible Functions,  , Dos-compatible Variables, The Dos-Compatible Library
@section Dos-compatible Functions

The following table lists all the functions (or statements) documented in the
Software Manual from ImageNation (in the same order),
and reports their status in the compatibility library.
Most of the functions which should return @t{void}, do actually return
@t{int}. This should not be a problem.

@table @code
@item void acquire(void);
@itemx void acquiref(void);
        Supported.
@item blank
        Supported.
@item void board_off(void);
@itemx void board_on(void);
        Supported (not fully functional yet).
@item int clear_field_counter(void);
@itemx int clear_field_counter_high(void);
        Supported.
@item CLEAR_PORTS
        Not yet.
@item void clr(int bit);
        Supported.
@item void copy_line(BYTE *buf, WORD row, BYTE dir, BYTE orient);
        Not yet.
@item void cx_command(int command);
        Supported.
@item void dec_page;
        Supported.
@item void display
        Supported.
@item void erase_ram(void);
        Not yet.
@item void exit_library(void);
        This only closes the currently open device.
@item void fill_column(WORD column, int color);
@itemx void fill_ram(int color);
@itemx void fill_row(WORD row, int color);
        Not suppored, yet.
@item int get_address(void);
        Not supported. It shouldn't be invoke by the user, anyways.
@item long get_clock(void);
        Not supported. I have to think about it...
@item void get_column(BYTE *buf, WORD column);
        Not yet.
@item int get_page;
        Supported.
@item int get_pixel(WORD x, WORD y);
@itemx void get_rectangle(BYTE huge *buf, WORD x1, WORD y1, WORD dx, WORD dy);
@itemx void get_row(BYTE *buf, WORD row);
        Not yet.
@item int grab(void);
@itemx int grab_field(void);
@itemx int grab_specific(int field);
@itemx int grab_specific_field(int field);
        Supported. But the return value is always zero. @t{grab_specific()}
        is the same as @t{grab()}, because I don't care about these details.
        The same net effect can be achieved by grabbing one specific field
        without waiting for the next blanking, and then grabbing 
@item WORD grab_triggered(WORD delay, WORD timeout);
        Not supported, yet.
@item void gray_scale_fill(void);
        Not supported.
@item int have_egavga(void);
        Not supported. It doesn't make sense.
@item void high_res;
@itemx void inc_page;
        Supported.
@item char *init_library(void);
        Supported: it opens @t{/dev/cxg0} and returns
        @t{NULL} or @t{strerror(errno)}
@itemx int internal_sync(void);
        Supported.
@item void load_input_lut(int address, int data);
@itemx void load_input_lut_buf(int *buf);
@itemx void load_output_lut(int address, int data);
@itemx void load_output_lut_buf(int *buf);
@itemx void load_overlay_lut(int address, int red, int green, int blue);
@itemx void load_rgb_lut(int address, int red, int green, int blue);
@itemx void load_rgb_lut_buf(RGB buf[]);
        Lut management is not available in this release.
@item void low_res;
        Supported.
@item void put_column(BYTE *buf,WORD column);
@itemx int put_pixel(WORD x, WORD y, int color);
@itemx void put_rectangle(BYTE *buf, WORD x1, WORD y1, WORD dx, WORD dy);
@itemx void put_row(BYTE *buf,WORD row);
        Not supported, yet.
@item void ram_off(void);
@itemx void ram_on(void);
        Supported.
@item int read_dips(void);
@itemx int read_field_counter_high(void);
@itemx int read_field_counter_low(void);
        Supported
@item int read_file_to_buf(char *fname, BYTE huge *buf, DWORD buflen);
@itemx int read_file_to_ram(char *fname);
        Block transfer is not implemented, by now.
@item int read_key(void);
@itemx int read_revision(void);
@itemx int read_status2(void);
        Supported.
@item void RELOAD_PORTS(int *tmp);
        Not yet.
@item void reset_cx(void);
        Supported, not fully functional.
@item void SAVE_PORTS(int *tmp);
        Not yet.
@item int segment_vacant(int addr);
        Not yet.
@item char *select_fg(int index);
        Not supported. Maybe, in the future...
@item void set(int bit);
@itemx int set_address(int addr);
@itemx int set_ccir(void);
        Supported.
@item void set_display_mask(int mask);
@item void set_gain(int gain);
@item void set_gross_gain(int ggain);
        Not yet.
@item int set_half_page(int row);
@item int set_interrupt_polarity(int pos);
        Not supported. Since the user shouldn't touch hardware,
        they won't ever be.
@item int set_ntsc(void);
        Supported.
@item void set_offset(int offset);
@itemx void set_overlay_mask(int mask);
        Not supported, by now.
@itemx int set_trig_edge_sensitive(void);
@itemx int set_trig_level_sensitive(void);
@itemx int set_trig_polarity(int pol);
@itemx int show_both_fields(void);
@itemx int show_field(int field);
@itemx int status(int bit);
@itemx int sync_to_video(void);
@itemx int toggle(int bit);
@itemx void unblank;
        Supported        
@item void vga_off(void);
@item void vga_on(void);
        Not supported, and don't make sense under Linux.
@item int waitvb(void);
@item int waitvb_field(int field);
        Supported.
@item WORD wait_for_trigger(WORD timeout);
        Not yet.
@item int write_buf_to_file(char *fname, int erase, BYTE *buf, DWORD buflen);
@item int write_ram_to_file(char *fname, int erase);
        Not yet
@item void zip_dn(void);
@item void zip_up(void);
        Not supported. I didn't understand them, either.
@end table

Averaging, text-drawing and graphic drawing functions are not
available. I plan to do drawing under Linux, but I don't know
if I'll ever make dos compatibility.

@ignore
@end ignore


%##########################################################################
@node The Sample Programs, Function Index, The Dos-Compatible Library, Top
@chapter The Sample Programs

@menu
* Minors::                      
* cxg_check::                   
* cxg_show::                    
* cxg_grab::                    
* cxg_xgrab::                   
* Pacco Stuff::                 
@end menu

%=========================================================================
@node Minors, cxg_check, The Sample Programs, The Sample Programs
@section Minor samples
@cindex testing the board

There are a few minor sources within the distribution: they are not
documented nor installed. They're tools I used to help my development,
and are part of the distribution just for my convenience.
You can look at them if you're interested.

@t{test} is is a simple program to issue low-level commands. You can
invoke @t{./test} without arguments to get a short help.

@t{roitest} gets a list of regions of interest on command line (using
the X-geometry representation and prints them continuously on stdout.

@t{seltest} gets an optional device name and two numbers and uses 
@t{read()} and @t{select()} to check workings of blocking read.

%=========================================================================
@node cxg_check, cxg_show, Minors, The Sample Programs
@section The @t{cxg_check} Program

@t{cxg_check} is a tool to report all available information about the
board(s) you have in your computer. It can also be used to monitor the
board(s) while an application is running.

Without cmdline options, it will print system-wide and software information,
and will look for any available device to return informationa bout them.
If commandline arguments are specified, only the specified devices will be
tested.

I usually invoke ``@t{./cxg_check /dev/cxg0f}'' to force autodetection of
the irq line. @xref{The /dev Nodes}.

%=========================================================================
@node cxg_show, cxg_grab, cxg_check, The Sample Programs
@section The @t{cxg_show} Program

@t{cxg_show} displays live video on an ascii terminal. The program reads
@t{argv[1]} (or standard input) as a raw device, puts it to the desired
resolution and draws data as an 8-level gray scale using ascii
characters. It is installed along with the driver, as it may be useful
to test the camera without firing up X.

The program is a small utility, and not too polished. It adapts the
output size to its stderr, and defaults to 80x50 if stderr is not a tty.

A little more functionality is available on the command line, but I haven't
found the time to document it here.

%=========================================================================
@node cxg_grab, cxg_xgrab, cxg_show, The Sample Programs
@section The @t{cxg_grab} Program

This is a cmdline-driven program to grab sequences of regions of interest,
saving them directly to disk without need to fire up X. Unfortunately,
it isn't eworking, yet.

%=========================================================================
@node cxg_xgrab, Pacco Stuff, cxg_grab, The Sample Programs
@section The @t{cxg_xgrab} Program

This program is a small Tk script, which displays grabbed images. If has
buttons to resize and move the region of the frame being grabbed, and
can save the image to a file.

%=========================================================================
@node Pacco Stuff,  , cxg_xgrab, The Sample Programs
@section The @t{pacco/*} Files

The @t{pacco} directory contains partial source for a tool I used, which
uses the Pacco tool (iride.unipv.it:/pub/Pacco).

The files are one C source and one Tcl source. They are in the distribution
to show how easy it is to grab and have live display (with the right tools
handy). Nothing is installed here.

The ``cinema'' script in the pacco directory is a simple live-video
application.

%##########################################################################
@node Function Index,  , The Sample Programs, Top
@unnumbered API Index

@printindex fn

%@iftex
%@unnumbered Table of Contents
%@contents
%@end iftex


@bye

/*
 * This is because Linus uses 4-wide tabstops,
 * forcing me to use the same default to manage kernel sources
 */

/* Local Variables: */
/* tab-width:8      */
/* End:             */
