/** @file sample_apci1710.c
 
   This demonstarte how to use digital I/O in user mode.
 
   @par CREATION  
   @author Krauth Julien
   @date   30.05.06
   
   @par VERSION
   @verbatim
   $LastChangedRevision:$
   $LastChangedDate:$
   @endverbatim   
   
   @par LICENCE
   @verbatim
    Copyright (C) 2009  ADDI-DATA GmbH for the source code of this module.
        
    ADDI-DATA GmbH
    Airpark Business Center
    Airport Boulevard B210
    77836 Rheinm�nster
    Germany
    Tel: +49(0)7229/1847-0
    Fax: +49(0)7229/1847-200
    http://www.addi-data-com
    info@addi-data.com
        
   This program is free software; you can redistribute it and/or modify it under 
   the terms of the GNU General Public License as published by the Free Software 
   Foundation; either version 2 of the License, or (at your option) any later version.

   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 program; if not, write to the Free Software Foundation, 
   Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

   You shoud also find the complete GPL in the COPYING file 
   accompanying this source code.
   @endverbatim   
 */ 

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>

#include <apci1710.h>

#include "sample_apci1710_common.h"

//--------------------------------------------------------------------------------

/**
 * @brief Digital output sample for APCI-1710 module
 * @param fd File descriptor of the opened APCI-1710 device
 */
void sample (int fd)
    {
    unsigned char  b_ModuleNbr = 1;             // Module number to test
    unsigned char  b_ChannelCpt;        // Channel counter
    char *        pc_ChannelArray = {"HAB"};
    int            i_ReturnValue;           // Return error code
    unsigned char b_ArgArray[3];


    /* Print sample information */
    printf ("\n+---------------------------------------------------+");
    printf ("\n| APCI-1710 Digital I/O:                            |");
    printf ("\n| Digital channel output sample                     |");
    printf ("\n| Channel A and channel B for output                |");
    printf ("\n+---------------------------------------------------+");

    /* 
     * Initialise the digital I/O module
     * Channel A and Channel B for input
     */
     
     /* Module number to configure (0 to 3).*/
    b_ArgArray[0] = b_ModuleNbr;
    
    /*
     * Channel A mode selection
     * 0 : Channel used for digital input
     * 1 : Channel used for digital output
     */    
    b_ArgArray[1] = 1;

    /*
     * Channel B mode selection
     * 0 : Channel used for digital input
     * 1 : Channel used for digital output
     */    
    b_ArgArray[2] = 1;
            
    i_ReturnValue = ioctl (fd,CMD_APCI1710_InitDigitalIO, b_ArgArray);

    /* Test the return value */
    switch (i_ReturnValue)
        {
        case 0:
        printf ("\nCMD_APCI1710_InitDigitalIO OK");
        break;

        case 1:
        printf ("\nCMD_APCI1710_InitDigitalIO error");
        printf ("\nError = %d. The handle parameter of the board is wrong", i_ReturnValue);
        break;

        case 2:
        printf ("\nCMD_APCI1710_InitDigitalIO error");
        printf ("\nError = %d. The module parameter is wrong", i_ReturnValue);
        break;

        case 3:
        printf ("\nCMD_APCI1710_InitDigitalIO error");
        printf ("\nError = %d. The module is not a digital I/O module", i_ReturnValue);
        break;

        case 4:
        printf ("\nCMD_APCI1710_InitDigitalIO error");
        printf ("\nError = %d. Bi-directional channel A configuration error", i_ReturnValue);
        break;
    
        case 5:
        printf ("\nCMD_APCI1710_InitDigitalIO error");
        printf ("\nError = %d. Bi-directional channel B configuration error", i_ReturnValue);
        break;
    
        default:
        printf ("\nCMD_APCI1710_InitDigitalIO error");
        printf ("\nError = %d", i_ReturnValue);
        break;
        } // switch (i_ReturnValue)

        /* Set the digital I/O output memory on */
        i_ReturnValue = ioctl (fd,CMD_APCI1710_SetDigitalIOMemoryOn, b_ModuleNbr);

        /* Test the return value */
        switch (i_ReturnValue)
            {
            case 0:
            printf ("\nCMD_APCI1710_SetDigitalIOMemoryOn OK");
            break;

            case 1:
            printf ("\nCMD_APCI1710_SetDigitalIOMemoryOn error");
            printf ("\nError = %d. The handle parameter of the board is wrong", i_ReturnValue);
            break;

            case 2:
            printf ("\nCMD_APCI1710_SetDigitalIOMemoryOn error");
            printf ("\nError = %d. The module parameter is wrong", i_ReturnValue);
            break;

            case 3:
            printf ("\nCMD_APCI1710_SetDigitalIOMemoryOn error");
            printf ("\nError = %d. The module is not a digital I/O module", i_ReturnValue);
            break;

            case 4:
            printf ("\nCMD_APCI1710_SetDigitalIOMemoryOn error");
            printf ("\nError = %d. Digital I/O not initialised", i_ReturnValue);
            break;

            default:
            printf ("\nCMD_APCI1710_SetDigitalIOMemoryOn error");
            printf ("\nError = %d", i_ReturnValue);
            break;
            } // switch (i_ReturnValue)

        /* Set the digital outputs on */
        for (b_ChannelCpt = 0; b_ChannelCpt < 3; b_ChannelCpt ++)
            {
            printf ("\n\nSet digital output %c on", pc_ChannelArray [b_ChannelCpt]);
            printf ("\nWait 2 seconds");
            sleep (2);

            /* Set the digital output on */
            
            b_ArgArray[0] = b_ModuleNbr;
            b_ArgArray[1] = b_ChannelCpt;        
            i_ReturnValue = ioctl (fd,CMD_APCI1710_SetDigitalIOChlOn, b_ArgArray);            

            /* Test the return value */
            switch (i_ReturnValue)
                {
                case 0:
                printf ("\nCMD_APCI1710_SetDigitalIOChlOn for channel %c OK", pc_ChannelArray [b_ChannelCpt]);
                break;

                case 1:
                printf ("\nCMD_APCI1710_SetDigitalIOChlOn channel %c error", pc_ChannelArray [b_ChannelCpt]);
                printf ("\nError = %d. The handle parameter of the board is wrong", i_ReturnValue);
                break;

                case 2:
                printf ("\nCMD_APCI1710_SetDigitalIOChlOn channel %c error", pc_ChannelArray [b_ChannelCpt]);
                printf ("\nError = %d. The module parameter is wrong", i_ReturnValue);
                break;
                
                case 3:
                printf ("\nCMD_APCI1710_SetDigitalIOChlOn channel %c error", pc_ChannelArray [b_ChannelCpt]);
                printf ("\nError = %d. The module is not a digital I/O module", i_ReturnValue);
                break;
                
                case 4:
                printf ("\nCMD_APCI1710_SetDigitalIOChlOn channel %c error", pc_ChannelArray [b_ChannelCpt]);
                printf ("\nError = %d. The selected digital output is wrong", i_ReturnValue);
                break;
                
                case 5:
                printf ("\nCMD_APCI1710_SetDigitalIOChlOn channel %c error", pc_ChannelArray [b_ChannelCpt]);
                printf ("\nError = %d. Digital I/O not initialised", i_ReturnValue);
                break;
                
                case 6:
                printf ("\nCMD_APCI1710_SetDigitalIOChlOn channel %c error", pc_ChannelArray [b_ChannelCpt]);
                printf ("\nError = %d. The digital channel A is used for input", i_ReturnValue);
                break;
                
                case 7:
                printf ("\nCMD_APCI1710_SetDigitalIOChlOn channel %c error", pc_ChannelArray [b_ChannelCpt]);
                printf ("\nError = %d. The digital channel B is used for input", i_ReturnValue);
                break;
                
                default:
                printf ("\nCMD_APCI1710_SetDigitalIOChlOn channel %c error", pc_ChannelArray [b_ChannelCpt]);
                printf ("\nError = %d", i_ReturnValue);
                break;
                } // switch (i_ReturnValue)
            }

        /* Set the digital outputs off */
        for (b_ChannelCpt = 0; b_ChannelCpt < 3; b_ChannelCpt ++)
            {
            printf ("\n\nSet digital output %c off", pc_ChannelArray [b_ChannelCpt]);
            printf ("\nWait 2 seconds");
            sleep (2);

            /* Set the digital output on */
            b_ArgArray[0] = b_ModuleNbr;
            b_ArgArray[1] = b_ChannelCpt;        
            i_ReturnValue = ioctl (fd,CMD_APCI1710_SetDigitalIOChlOff, b_ArgArray);    

            /* Test the return value */
            switch (i_ReturnValue)
                {
                case 0:
                printf ("\nCMD_APCI1710_SetDigitalIOChlOff for channel %c OK", pc_ChannelArray [b_ChannelCpt]);
                break;
                
                case 1:
                printf ("\nCMD_APCI1710_SetDigitalIOChlOff channel %c error", pc_ChannelArray [b_ChannelCpt]);
                printf ("\nError = %d. The handle parameter of the board is wrong", i_ReturnValue);
                break;
                
                case 2:
                printf ("\nCMD_APCI1710_SetDigitalIOChlOff channel %c error", pc_ChannelArray [b_ChannelCpt]);
                printf ("\nError = %d. The module parameter is wrong", i_ReturnValue);
                break;
                
                case 3:
                printf ("\nCMD_APCI1710_SetDigitalIOChlOff channel %c error", pc_ChannelArray [b_ChannelCpt]);
                printf ("\nError = %d. The module is not a digital I/O module", i_ReturnValue);
                break;
                
                case 4:
                printf ("\nCMD_APCI1710_SetDigitalIOChlOff channel %c error", pc_ChannelArray [b_ChannelCpt]);
                printf ("\nError = %d. The selected digital output is wrong", i_ReturnValue);
                break;
                
                case 5:
                printf ("\nCMD_APCI1710_SetDigitalIOChlOff channel %c error", pc_ChannelArray [b_ChannelCpt]);
                printf ("\nError = %d. Digital I/O not initialised", i_ReturnValue);
                break;
                
                case 6:
                printf ("\nCMD_APCI1710_SetDigitalIOChlOff channel %c error", pc_ChannelArray [b_ChannelCpt]);
                printf ("\nError = %d. The digital channel A is used for input", i_ReturnValue);
                break;
                
                case 7:
                printf ("\nCMD_APCI1710_SetDigitalIOChlOff channel %c error", pc_ChannelArray [b_ChannelCpt]);
                printf ("\nError = %d. The digital channel B is used for input", i_ReturnValue);
                break;
                
                case 8:
                printf ("\nCMD_APCI1710_SetDigitalIOChlOff channel %c error", pc_ChannelArray [b_ChannelCpt]);
                printf ("\nError = %d. Digital Output Memory OFF", i_ReturnValue);
                break;
                
                default:
                printf ("\nCMD_APCI1710_SetDigitalIOChlOff channel %c error", pc_ChannelArray [b_ChannelCpt]);
                printf ("\nError = %d", i_ReturnValue);
                break;
                } // switch (i_ReturnValue)
            }

        /* Set the digital I/O output memory off */
        i_ReturnValue = ioctl (fd,CMD_APCI1710_SetDigitalIOMemoryOff, b_ModuleNbr);    

        /* Test the return value */
        switch (i_ReturnValue)
            {
            case 0:
            printf ("\nCMD_APCI1710_SetDigitalIOMemoryOff OK");
            break;
            
            case 1:
            printf ("\nCMD_APCI1710_SetDigitalIOMemoryOff error");
            printf ("\nError = %d. The handle parameter of the board is wrong", i_ReturnValue);
            break;
            
            case 2:
            printf ("\nCMD_APCI1710_SetDigitalIOMemoryOff error");
            printf ("\nError = %d. The module parameter is wrong", i_ReturnValue);
            break;
            
            case 3:
            printf ("\nCMD_APCI1710_SetDigitalIOMemoryOff error");
            printf ("\nError = %d. The module is not a digital I/O module", i_ReturnValue);
            break;
            
            case 4:
            printf ("\nCMD_APCI1710_SetDigitalIOMemoryOff error");
            printf ("\nError = %d. Digital I/O not initialised", i_ReturnValue);
            break;
            
            default:
            printf ("\nCMD_APCI1710_SetDigitalIOMemoryOff error");
            printf ("\nError = %d", i_ReturnValue);
            break;
            } // switch (i_ReturnValue)
    }

//--------------------------------------------------------------------------------

int main(int argc, char** argv)
{

    int * apci1710_card_fd;
    unsigned int apci1710_card_number = 0;
    {
        apci1710_card_number = apci1710_find_cards(&apci1710_card_fd);
        
        printf("total: %d cards\n",apci1710_card_number);
    }    
    
    {
        int i;
        for (i=0;i< apci1710_card_number; i++)
        {
            printf("\n+++++++++++++++++++++++++++++++++++++\nrunning test on device of minor number %d\n+++++++++++++++++++++++++++++++++++++\n\n\n",i);            
            /* Compare logic sample */
            sample (apci1710_card_fd[i]);    
        }
    }

    

    return 0;
}
//--------------------------------------------------------------------------------
