/******************************************************************************
 * $Revision: 423 $
 * $Date:: 2017-04-07 16:03:30 +0900#$
 *****************************************************************************/
/* __DISCLAIMER_START__                                                      */
/******************************************************************************
* (c)2017, Cypress Semiconductor Corporation
* or a subsidiary of Cypress Semiconductor Corporation. All rights
* reserved.
*
* This software, including source code, documentation and related
* materials ( "Software" ), is owned by Cypress Semiconductor
* Corporation or one of its subsidiaries ( "Cypress" ) and is protected by
* and subject to worldwide patent protection (United States and foreign),
* United States copyright laws and international treaty provisions.
* Therefore, you may use this Software only as provided in the license
* agreement accompanying the software package from which you
* obtained this Software ( "EULA" ).
*
* If no EULA applies, Cypress hereby grants you a personal, nonexclusive,
* non-transferable license to copy, modify, and compile the
* Software source code solely for use in connection with Cypress' s
* integrated circuit products. Any reproduction, modification, translation,
* compilation, or representation of this Software except as specified
* above is prohibited without the express written permission of Cypress.
*
* Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO
* WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING,
* BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE. Cypress reserves the right to make
* changes to the Software without notice. Cypress does not assume any
* liability arising out of the application or use of the Software or any
* product or circuit described in the Software. Cypress does not
* authorize its products for use in any products where a malfunction or
* failure of the Cypress product may reasonably be expected to result in
* significant property damage, injury or death ( "High Risk Product" ). By
* including Cypress' s product in a High Risk Product, the manufacturer
* of such system or application assumes all risk of such use and in doing
* so agrees to indemnify Cypress against all liability.
******************************************************************************/
/* __DISCLAIMER_END__                                                        */
/*****************************************************************************
 ** \file icu.h
 **
 ** Headerfile for Input Capture Unit (ICU) functions
 **
 ** History:
 ** - 2014-06-25  0.01  ST  First version
 *****************************************************************************/

#ifndef __ICU_H__
#define __ICU_H__

/*****************************************************************************/
/* Include files                                                             */
/*****************************************************************************/
#include "pdl.h"


/* C binding of definitions if building with C++ compiler */
#ifdef __cplusplus
extern "C"
{
#endif

/*****************************************************************************/
/* Global pre-processor symbols/macros ('#define')                           */
/*****************************************************************************/
/* Each ICU has two channels */
#define ICU_CHANNEL_COUNT    2   


/**
 *****************************************************************************
 ** \defgroup IcuGroup Input Capture Unit (ICU)
 **
 ** \brief This section describes the interface for the Input Capture Unit.
 **
 ** \note If you want to detect only simple line changes of external IO pins,
 **       you should use the External Interrupt Module (EIC) instead.
 **
 ** Provided functions of ICU module:
 ** - Icu_Init() (Initialization of ICU module)
 ** - Icu_SetChannelConfig() (Store callback and Enable a ICU)
 ** - Icu_EnableChannel() (Enable a ICU channel)
 ** - Icu_DisableChannel() (Disable a ICU channel)
 ** - Icu_GetCount() (Get a Capture data)
 **
 ** Each ICU is connected with a dedicated Free Running Timer (FRT). 
 ** The ICU detects rising, falling, or both edges of an external input signal 
 ** and stores the 32-bit Free-Running Timer value at that time in a register 
 ** and generates an interrupt (if configured accordingly) upon detection of a 
 ** rising or falling edge. 
 **
 ** To use the ICU first the module has to be initialized with Icu_Init(). After
 ** that the needed ICU channel(s) can be configured and then enabled. Enabling
 ** can be done either directly when configuring 
 ** (stc_icu_channel_config_t#enEdgeDetection != IcuNoEdge) or by calling 
 ** Icu_EnableChannel(). From this on, the ICU will work and the interrupt 
 ** callback (stc_icu_channel_config_t#pfnCalback) for the enabled channel 
 ** will be called each time an event is detected.
 ** For turning off a channel Icu_DisableChannel() has to be called.
 **
 **
 *****************************************************************************/
//@{

/*****************************************************************************
 * Global type definitions
 *****************************************************************************/
 /**
 *****************************************************************************
 ** \brief ICU edge detection
 ** 
 ** Enum for the different possible edge detection modes
 *****************************************************************************/
typedef enum en_icu_edge_detection
{
    IcuNoEdge      = 0x00, /*!< Edge detection is disabled, hence the channel is disabled */
    IcuRisingEdge  = 0x01, /*!< Detect only rising edges */
    IcuFallingEdge = 0x02, /*!< Detect only falling edges */
    IcuBothEdges   = 0x03  /*!< Detect all edges */
} en_icu_edge_detection_t;


/**
 *****************************************************************************
 ** \brief ICU channel configuration
 ** 
 ** The ICU configuration is done on a per channel basis
 *****************************************************************************/
typedef struct stc_icu_channel_config
{
    /** Set edge detection mode (enables the channel if != IcuNoEdge) */
    en_icu_edge_detection_t   enEdgeDetection; 

    /** \brief Interrupt callback for edge detection event interrupt */
    /** If a NULL pointer is provided by the application, the corresponding */
    /** interrupt will not be enabled. */
    func_ptr_t                pfnCallback;  
} stc_icu_channel_config_t;


/**
 *****************************************************************************
 ** \brief Datatype for holding internal data needed for ICU
 **
 ** This struct is used to store the interrupt callback function for the ICU
 *****************************************************************************/
typedef struct stc_icu_intern_data
{
    /** Callback for interrupts on edge detection for channel 0 */
    func_ptr_t  pfnCallbackChannel0 ;
    /** Callback for interrupts on edge detection for channel 1 */
    func_ptr_t  pfnCallbackChannel1 ;
} stc_icu_intern_data_t ;


/*****************************************************************************/
/* Global variable declarations ('extern', definition in C source)           */
/*****************************************************************************/

/*****************************************************************************/
/* Global function prototypes ('extern', definition in C source)             */
/*****************************************************************************/


/*****************************************************************************
 * Global function prototypes
 *****************************************************************************/
extern en_result_t Icu_Init( volatile stc_icun_t* pstcIcu ) ;
extern en_result_t Icu_SetChannelConfig( 
                                     volatile stc_icun_t* pstcIcu, 
                                     uint8_t u8Channel, 
                                     const stc_icu_channel_config_t* pstcConfig
                                    ) ;
extern en_result_t Icu_EnableChannel( volatile stc_icun_t* pstcIcu, 
                                      uint8_t u8Channel, 
                                      en_icu_edge_detection_t enEdgeDetection
                                    ) ;
extern en_result_t Icu_DisableChannel( volatile stc_icun_t* pstcIcu, 
                                       uint8_t u8Channel 
                                     ) ;
extern en_result_t Icu_GetCount( volatile stc_icun_t* pstcIcu,
                                 uint8_t u8Channel,
                                 uint32_t* data
                               );

//@} // IcuGroup


#ifdef __cplusplus
}
#endif

#endif /* __ICU_H__ */
/*****************************************************************************/
/* EOF (not truncated)                                                       */
/*****************************************************************************/
