/************************************************************************
 *                                                                      *
 *  board.h  ---  real time daq kernel functions API.                   *
 *                                                                      *
 *  This file is open source software; you can redistribute it and/or   *
 *  modify it under the terms of the version 2 of GNU General Public    *
 *  License as published by the Free Software Foundation.               *
 *                                                                      *
 *  This program is distributed in the hope that it will be useful,     *
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of      *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the       *
 *  GNU General Public License for more details.                        *
 *                                                                      *
 *  You should have received a copy of the GNU General Public License   *
 *  along with this package; if not, write to the Free Software         *
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.           *
 *  or look at http://www.gnu.org/fsf/fsf.html                          *
 *                                                                      *
 *  Copyleft, Peter Wurmsdobler, control.com                            *
 *                                                                      *
 ************************************************************************/

/* This header file describes function prototypes for accessing
   multi-function local i/o boards in a PCI or ISA bus. Most such
   boards offer a complex functionalilty which might be interesting
   for specific applications. In a control application, however,
   simple read and write functions are sufficient. And if you use
   real time linux, most fancy board functions are not necessary.
 */
 
/***********************************************************************
 * General functions                                                   *
 ***********************************************************************/

/* We need to open and close boards, which might depend whether we
   are in kernel or user space. 
 */
#ifdef __KERNEL__

/* In kernel space we define a structure for private data in a linked list. 
 */
typedef struct {} board_t *boards=NULL;

/* will look for board instances, append a structure and fill it in
 */
int init_module (void)

/* release resources
 */
int cleanup_module (void)

#else

/* in user space we will make a library call to board_open/board_close.
   These and all io related functions will of course translate to 
   open/read/write/ioctl/close system calls to access the kernel
   functions which have the same name and functionality.
 */

/* open a board and get an id
 */
extern int board_init (void);

/* close a board with id
 */
extern int board_cleanup (int board);

#endif


/***********************************************************************
 * Analog input functions ...                                          *
 ***********************************************************************/

/* Nowadays, boards can do quite fancy things, FIFOs, scanning a
   set of channels, DMA, interrupts etc. For two reasons. Mircosoft
   Windows is not real time enough to do reliable DAQ, and if you
   need to stream a lot of data, FIFO, DMA and interrupt use are
   the only way. In control, however, you read values, do the control
   algorithm and logic, then write. So for just a couple of channels
   per boards PIO is fast enough, and for more channels, programming
   a channel scan and getting it should work also.
 */

/* select adc mode
 */
extern void board_ai_set_mode (int board, unsigned char mode);

/* select channel for successive conversion
 */
extern void board_ai_adc_select (int board, unsigned short int channel);

/* program ADC for successive conversion, with both channel 
 * and range as defined in header file.
 */
extern void board_ai_adc_program (int board, unsigned short int channel,
    unsigned short int range);

/* get a single analog value given that channel is already
 * selected and ints range set, mode is software.
 */
extern int board_ai_get_value0 (int board, unsigned short int *value);

/* get a single analog value (int board, channel); given that its range set.
 */
extern int board_ai_get_value1 (int board, unsigned short int *value,
    unsigned short int channel);

/* get a single analog value (int board, channel, range);.
 */
extern int board_ai_get_value2 (int board, unsigned short int *value,
    unsigned short int channel, unsigned short int range);

/* start a channel scan with list, number of channels and sampling time[us]
 * mode has to be set appropriately, extern (pre,post,middle) or internal
 */
extern int board_ai_start_scan (int board, unsigned short int *channellist,
    unsigned short int nchannels, unsigned int time, unsigned char mode);

/* Once the scan has been started, the application is responsible
 * for picking up values from the fifos periodically. If an interupt
 * is available, this can be done by the respective routine. The
 * rest depends on the application.
 */
extern int board_ai_get_scan (int board, unsigned short int *value);

/* Stop analogue input scan.
 */
extern void board_ai_stop_scan (int board, void);


/***********************************************************************
 * Analog output functions ...                                         *
 ***********************************************************************/

/* Analog output does in general not take long, so some 
   basic functions should be sufficient.
 */

/* activate channel for successive DA conversion
 */
extern void board_ao_dac_select (int board, unsigned short int channel);

/* program DAC for successive DA conversion with both channel 
 * and range as defined in header file.
 */
extern void board_ao_dac_program (int board, unsigned short int channel,
    unsigned short int range);

/* set a single analog value given that channel is already
 * selected and ints range set value mapped to 16bit.
 */
extern void board_ao_set_value0 (int board, unsigned short int value);

/* set a single analog value (channel) given that its range set.
 * value is mapped to 16bit independently of DAC.
 */
extern void board_ao_set_value1 (int board, unsigned short int value, 
    unsigned short int channel);

/* set a single analog value (channel,range).
 * value is mapped to 16bit independently of DAC.
 */
extern void board_ao_set_value2 (int board, unsigned short int value,
    unsigned short int channel, unsigned short int range);


/***********************************************************************
 * Digital input/output functions ...                                  *
 ***********************************************************************/

/* Digital i/o comes in various flavours, only inut, only output
   or programmable direction, mostly in 8 bit blocks, ports.
 */

/* get byte from port "nport".
 */ 
extern unsigned char board_di_get_byte (int board, unsigned short int nport);

/* get bit #"nbit" from port "nport".
 */ 
extern unsigned short int board_di_get_bit (int board, 
    unsigned short int nport, unsigned short int nbit);

/* set byte "byte" on port "nport"
 */ 
extern void board_do_set_byte (int board, unsigned char byte,
    unsigned short int nport);

/* set bit "bit" with #"nbit" on port "nport".
 */ 
extern void board_do_set_bit (int board, unsigned short int bit,
    unsigned short int nport, unsigned short int nbit);

/* board_dio_set_byte  ---  set byte at port 0-5 by "byte".
 */ 
extern void board_dio_set_byte (int board, unsigned char byte,
    unsigned short int nport);

/* set bit at port, channel 0-7, by "bit" 0 or 1.
 */ 
extern void board_dio_set_bit (int board, unsigned short int bit,
    unsigned short int nport, unsigned short int nbit);
    
/* board_dio_get_byte  ---  get byte at port 0-5 into "byte"
 */ 
extern unsigned char board_dio_get_byte (int board, unsigned short int nport);

/* board_dio_get_bit  ---  get bit at port 0-5, channel 0-7,
 * into "bit".
 */ 
extern unsigned short int board_dio_get_bit (int board, 
    unsigned short int nport, unsigned short int nbit);

/* config ports as INPUT or OUTPUT, if output, set to zero.
 */ 
extern void board_dio_conf_port (int board, unsigned short int nport,
    unsigned char type);

