/** @file sample_apci1710_pwm.c
 
   This demonstrates how to use the PWM in user mode.
 
   @par CREATION  
   @author ADDI-DATA
   @date   22-3-2016
   
   @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 Rheinmuenster
    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 <apci1710.h>

#include "sample_apci1710_common.h"

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

static int gi_fd; /* Global file handle on the board to use */

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

/**
 * @brief PWM sample for APCI-1710 module
 * @param fd Device file descriptor
 */
void sample (int fd)
{
    uint8_t   b_ModuleNbr       = 0;
    uint8_t   b_PWM = 0;
        uint8_t     b_ClockSelection = APCI1710_40MHZ;
        uint8_t     b_TimingUnit =2;
        uint32_t   ul_LowTiming =500;
        uint32_t   ul_HighTiming =500;
    uint32_t ui_ArgArray[7];    
    int       i_ReturnValue = 0;
        
    gi_fd = fd;

    /* Initialise the PWM */
    ui_ArgArray[0] = (uint32_t) b_ModuleNbr;    // The module to use (0 to 3).
    ui_ArgArray[1] = (uint32_t) b_PWM;         // PWM selection (0 to 3)
    ui_ArgArray[2] = (uint32_t) b_ClockSelection;    //clock selection 
    ui_ArgArray[3] = (uint32_t) b_TimingUnit;    // Timing unit
    ui_ArgArray[4] = ul_LowTiming;                // Low timing
    ui_ArgArray[5] = ul_HighTiming;                // High timing

                            
    i_ReturnValue = ioctl (fd,CMD_APCI1710_InitPWM, ui_ArgArray);

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

        /* Enable the PWM */
        ui_ArgArray[0] = (uint32_t) b_ModuleNbr;   // The module to use (0 to 3).
        ui_ArgArray[1] = (uint32_t) b_PWM;        // PWM (0 to 3)
        ui_ArgArray[2] = 0;                      // start_lvl
        ui_ArgArray[3] = 0;                  // stop_mode
        ui_ArgArray[4] = 0;                     // stop_lvl
        ui_ArgArray[5] = 0;                     // b_ExternGate
        ui_ArgArray[6] = APCI1710_DISABLE;    // Interrupt handling
                            
        i_ReturnValue = ioctl (fd,CMD_APCI1710_EnablePWM, ui_ArgArray);

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

            printf ("\n\n");
            sleep (5);
                        
                                          
                        /* Set new PWM timing */
                        ui_ArgArray[0] = (uint32_t) b_ModuleNbr;    // The module to use (0 to 3).
                        ui_ArgArray[1] = (uint32_t) b_PWM;         // PWM selection (0 to 3)
                        ui_ArgArray[2] = (uint32_t) b_TimingUnit;    // Timing unit
                        ui_ArgArray[3] = 1000;                // Low timing
                        ui_ArgArray[4] = 200;                // High timing
                        
                    i_ReturnValue = ioctl (fd,CMD_APCI1710_SetNewPWMTiming, ui_ArgArray);
                    
                
                    
                    /* Test the return value */
             switch (i_ReturnValue)
            {
            case 0:
            printf ("\nCMD_APCI1710_SetNewPWMTiming OK");
                        sleep(5);
                        
                        /* Disable the PWM */
            ui_ArgArray[0] = (uint32_t) b_ModuleNbr;// The module to use (0 to 3).
            ui_ArgArray[1] = (uint32_t) b_PWM;    // PWM (0 to 3)
                            
            i_ReturnValue = ioctl (fd,CMD_APCI1710_DisablePWM, ui_ArgArray);

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

                case 1:
                printf ("\nCMD_APCI1710_DisablePWM error");
                printf ("\nError = %d. Module selection wrong", i_ReturnValue);
                break;

                case 2:
                printf ("\nCMD_APCI1710_DisablePWM error");
                printf ("\nError = %d. The module is not a PWM module", i_ReturnValue);
                break;

                case 3:
                printf ("\nCMD_APCI1710_DisablePWM error");
                printf ("\nError = %d.  PWM selection is wrong ", i_ReturnValue);
                break;

                case 4:
                printf ("\nCMD_APCI1710_DisablePWM error");
                printf ("\nError = %d. PWM not initialised see function", i_ReturnValue);
                break;
                                
                                case 5:
                printf ("\nCMD_APCI1710_DisablePWM error");
                printf ("\nError = %d. PWM not enabled see function ", i_ReturnValue);
                break;

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

                        
                        case 1:
                        printf ("\nCMD_APCI1710_SetNewPWMTiming error");
                        printf ("\nError = %d. Module selection is wrong", i_ReturnValue);
                        break;

                        case 2:
                        printf ("\nCMD_APCI1710_SetNewPWMTiming error");
                        printf ("\nError = %d. Not a PWM Module", i_ReturnValue);
                        break;

                        case 3:
                        printf ("\nCMD_APCI1710_SetNewPWMTiming error");
                        printf ("\nError = %d. PWM selection is wrong", i_ReturnValue);
                        break;
                        
                        case 4:
                        printf ("\nCMD_APCI1710_SetNewPWMTiming error");
                        printf ("\nError = %d. PWM not initialised ", i_ReturnValue);
                        break;

                        case 5:
                        printf ("\nCMD_APCI1710_SetNewPWMTiming error");
                        printf ("\nError = %d. Timing Unit selection is wrong", i_ReturnValue);
                        break;

                        case 6:
                        printf ("\nCMD_APCI1710_SetNewPWMTiming error");
                        printf ("\nError = %d. Low base timing selection is wrong", i_ReturnValue);
                        break;

                        case 7:
                        printf ("\nCMD_APCI1710_SetNewPWMTiming error");
                        printf ("\nError = %d. High base timing selection is wrong", i_ReturnValue);
                        break;
                    
                        default:
                        printf ("\nCMD_APCI1710_SetNewPWMTiming error");
                        printf ("\nError = %d. IOCTL Error", i_ReturnValue);
                        break;
                        }
                        break;

 
            case 1:
            printf ("\nCMD_APCI1710_EnablePWM error");
            printf ("\nError = %d. Module selection is wrong", i_ReturnValue);
            break;

            case 2:
            printf ("\nCMD_APCI1710_EnablePWM error");
            printf ("\nError = %d. The module is not a PWM module", i_ReturnValue);
            break;

            case 3:
            printf ("\nCMD_APCI1710_EnablePWM error");
            printf ("\nError = %d. PWM not initialised see function  ", i_ReturnValue);
            break;

            case 4:
            printf ("\nCMD_APCI1710_EnablePWM error");
            printf ("\nError = %d. PWM not initialised see function  ", i_ReturnValue);
            break;

            case 5:
            printf ("\nCMD_APCI1710_EnablePWM error");
            printf ("\nError = %d.  PWM start level selection is wrong ", i_ReturnValue);
            break;

            case 6:
            printf ("\nCMD_APCI1710_EnablePWM error");
            printf ("\nError = %d. PWM stop mode selection is wrong ", i_ReturnValue);
            break;

            case 7:
            printf ("\nCMD_APCI1710_EnablePWM error");
            printf ("\nError = %d. PWM stop level selection is wrong ", i_ReturnValue);
            break;

                        case 8:
            printf ("\nCMD_APCI1710_EnablePWM error");
            printf ("\nError = %d. Extern gate signal selection is wrong  ", i_ReturnValue);
            break;
                        
                        case 9:
            printf ("\nCMD_APCI1710_EnablePWM error");
            printf ("\nError = %d.Interrupt parameter is wrong  ", i_ReturnValue);
            break;
                        
                        case 10:
            printf ("\nCMD_APCI1710_EnablePWM error");
            printf ("\nError = %d. Interrupt function not initialised. ", i_ReturnValue);
            break;
                        
            default:
            printf ("\nCMD_APCI1710_EnablePWM error");
            printf ("\nIOCTL Error = %d.", i_ReturnValue);
            break;
            }

        break;

        case 1:
        printf ("\nCMD_APCI1710_InitPWM error");
        printf ("\nError = %d. Module selection wrong", i_ReturnValue);
        break;

        case 2:
        printf ("\nCMD_APCI1710_InitPWM error");
        printf ("\nError = %d. The module is not a PWM module", i_ReturnValue);
        break;

        case 3:
        printf ("\nCMD_APCI1710_InitPWM error");
        printf ("\nError = %d. PWM selection is wrong", i_ReturnValue);
        break;

        case 4:
        printf ("\nCMD_APCI1710_InitPWM error");
        printf ("\nError = %d. The selected input clock is wrong ", i_ReturnValue);
        break;

        case 5:
        printf ("\nCMD_APCI1710_InitPWM error");
        printf ("\nError = %d. Timing Unit selection is wrong ", i_ReturnValue);
        break;

        case 6:
        printf ("\nCMD_APCI1710_InitPWM error");
        printf ("\nError = %d. Low base timing selection is wrong", i_ReturnValue);
        break;
                
                case 7:
        printf ("\nCMD_APCI1710_InitPWM error");
        printf ("\nError = %d. High base timing selection is wrong ", i_ReturnValue);
        break;
                
               case 8:
        printf ("\nCMD_APCI1710_InitPWM error");
        printf ("\nError = %d. You can not use the 40MHz clock selection with this board ", i_ReturnValue);
        break;

        default:
        printf ("\nCMD_APCI1710_InitPWM error");
        printf ("\nIOCTL Error = %d.", i_ReturnValue);
        break;
        } // switch (i_ReturnValue)


    printf ("\nProgram concluded.");
}

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


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);
            
            /* PWM sample */
            sample (apci1710_card_fd[i]);    
        }
    }

    

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