/******************************************************************************
* $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 bt_pwm.h
**
** Headerfile for PWM
**
** History:
** - 2014-05-30  0.01  ST  First version
*****************************************************************************/

#ifndef __BSP_PWM_H__
#define __BSP_PWM_H__



    /*****************************************************************************/
    /* Global pre-processor symbols/macros ('define')                            */
    /*****************************************************************************/


    /**
    *****************************************************************************
    ** \defgroup PwmGroup Pulse Width Modulation (PWM)
    **
    ** \brief This section describes the interface for the Pulse Width Modulation.
    **
    ** Provided functions of PWM module:
    ** - Bt_Pwm_Init() (Initialization of PWM module)
    ** - Bt_Pwm_Start() (Set the cycle, the duty and to start a PWM)
    ** - Bt_Pwm_Stop() (Stop a PWM)
    **
    ** Pulse Width Modulations (PWMs) are used to obtain one-shot
    ** (rectangular wave) output or Continuous output.
    ** With their software programmable cycle and duty capability, possibility to
    ** postpone the start of PWM output signal generation by software and trigger
    ** an AD conversion, the PWMs comfortably fit into a broad range of
    ** applications.
    **
    ** Internally a PWM channel consists of a counter that counts down to the 0
    ** from defined cycle period (stc_pwm_cycle_config#u16Cycle).
    ** Part of this period the output goes high (or low if inverted),
    ** this is called the duty cycle. It is defined by the the duty value set
    ** with Bt_Pwm_Start().
    ** The duty value should be less or equal the period.
    **
    ** The first thing to do is to initialize the PWM by calling Bt_Pwm_Init().
    ** The configuration is depending on parameters(stc_pwm_config).
    **
    ** Then Set the cycle period and the duty cyclet.
    ** (i.e. how much of the whole cycle the PWM signal is high).
    ** Set the value to StartDelay(stc_pwm_cycle_config#u16StartDelay), If you
    ** want to delay the start of the PWM.
    ** When using the PWM as the trigger for ADC, is set to a value ADC Trigger
    ** (stc_pwm_cycle_config#u16AdcTriggerValue).
    ** Calling Bt_Pwm_Start() set the parameters(stc_pwm_cycle_config) and
    ** start the PWM.
    **
    **
    *****************************************************************************/
    //@{

    /*****************************************************************************
    * Global type definitions
    *****************************************************************************/

    /**
    *****************************************************************************
    ** \brief PWM trigger edge selection
    *****************************************************************************/
    typedef enum en_pwm_trigger_input_edge_selection
    {
        PwmSoftwareOnly = 0x0,   /*!< PWM is triggered by software */
        PwmRisingEdge   = 0x1,   /*!< PWM is triggered by a rising edge */
        PwmFallingEdge  = 0x2,   /*!< PWM is triggered by a falling edge */
        PwmBothEdges    = 0x3    /*!< PWM is triggered by a rising or a falling edge */
    } en_pwm_trigger_input_edge_selection_t ;



    /**
    *****************************************************************************
    ** \brief PWM clock prescaler
    *****************************************************************************/
    typedef enum en_pwm_clock_prescaler
    {
        PwmDiv1     = 0x0, /*!< Internal clock                      */
        PwmDiv4     = 0x1, /*!< Internal clock divided by 4         */
        PwmDiv16    = 0x2, /*!< Internal clock divided by 16        */
        PwmDiv128   = 0x3, /*!< Internal clock divided by 128       */
        PwmDiv256   = 0x4, /*!< Internal clock divided by 256       */
        PwmExClkRis = 0x5, /*!< External clock (rising-edge event)  */
        PwmExClkfal = 0x6, /*!< External clock (falling-edge event) */
        PwmExClkbot = 0x7, /*!< External clock (both-edges event)   */
        PwmDiv512   = 0x8, /*!< Internal clock divided by 512       */
        PwmDiv1024  = 0x9, /*!< Internal clock divided by 1024      */
        PwmDiv2048  = 0xa, /*!< Internal clock divided by 2048      */
        PwmDiv2     = 0xb, /*!< Internal clock divided by 2         */
        PwmDiv8     = 0xc, /*!< Internal clock divided by 8         */
        PwmDiv32    = 0xd, /*!< Internal clock divided by 32        */
        PwmDiv64    = 0xe  /*!< Internal clock divided by 64        */
    } en_pwm_clock_prescaler_t;

    /**
    *****************************************************************************
    ** \brief Cycle configuration
    *****************************************************************************/
    typedef struct stc_pwm_cycle_config
    {
        uint16_t           u16Cycle ;               /*!< PWM cycle */
        uint16_t           u16Duty ;                /*!< PWM duty */
        uint16_t           u16StartDelay ;          /*!< Delay on PWM start in count cycles */
        uint16_t           u16AdcTriggerValue ;     /*!< Generate ADC trigger on match with PWM counter value */
    } stc_pwm_cycle_config_t ;


    /**
    *****************************************************************************
    ** \brief PWM configuration
    *****************************************************************************/
    typedef struct stc_pwm_config
    {
        /** Sets clock prescaler. See #en_pwm_clock_prescaler_t. */
        en_pwm_clock_prescaler_t                enPrescaler;
        /** Trigger restarts PWM operation. TRUE: Enable restart, FALSE: Disable restart */
        boolean_t                               bRestartEnable;
        /** Pulse output mask. TRUE: Fixed at "L" output, FALSE: Normal output */
        boolean_t                               bPulseOutputMaskEnable;
        /** Select edge that triggers PWM. See #en_pwm_trigger_input_edge_selection_t. */
        en_pwm_trigger_input_edge_selection_t   enTriggerInputEdgeSelection;
        /** Normal or Inverse output polarity. TRUE: Inverse polarity, FALSE: Normal polarity */
        boolean_t                               bOutputPolarityInverse;
        /** Mode selection. TRUE: One shot, FALSE: Continuous */
        boolean_t                               bOneShotOperation;
        /** Callback for trigger interrupt */
        func_ptr_t                pfnTriggerCallback;
        /** Callback for duty match interrupt */
        func_ptr_t                pfnDutyMatchCallback;
        /** Callback for Underflow interrupt */
        func_ptr_t                pfnUnderflowCallback;

    } stc_pwm_config_t ;


    /**
    *****************************************************************************
    ** \brief Datatype for holding internal data needed for PWM
    **
    ** This struct is used to store the interrupt callback function for the PWM
    *****************************************************************************/
    typedef struct stc_pwm_intern_data
    {
        func_ptr_t       pfnTriggerCallback ;     /*!< Interrupt callback function pointer */
        func_ptr_t       pfnDutyMatchCallback ;   /*!< Interrupt callback function pointer */
        func_ptr_t       pfnUnderflowCallback ;   /*!< Interrupt callback function pointer */
    } stc_pwm_intern_data_t ;


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


    /*****************************************************************************
    * Global function prototypes
    *****************************************************************************/
    /*****************************************************************************/
    /* Local function prototypes ('static')                                      */
    /*****************************************************************************/
    extern void BtPwmIrqHandler(volatile stc_btn_pwm_t *pstcPwm, stc_pwm_intern_data_t *pstcPwmInternData);
    extern en_result_t Bt_Pwm_Init(volatile stc_btn_pwm_t *pstcPwm, stc_pwm_config_t *pstcConfig);
    extern en_result_t Bt_Pwm_Start(volatile stc_btn_pwm_t *pstcPwm, stc_pwm_cycle_config_t *pstcCycle, boolean_t bSwTrigger) ;
    extern en_result_t Bt_Pwm_Stop(volatile stc_btn_pwm_t *pstcPwm) ;
    extern stc_pwm_intern_data_t* BtPwmGetInternDataPtr(volatile stc_btn_pwm_t* pstcPwm);
    
    FN_IRQ_NOT_NESTED void Pwm_Isr_Pwm0(void);
    FN_IRQ_NOT_NESTED void Pwm_Isr_Pwm1(void);
    FN_IRQ_NOT_NESTED void Pwm_Isr_Pwm2(void);
    FN_IRQ_NOT_NESTED void Pwm_Isr_Pwm3(void);
    FN_IRQ_NOT_NESTED void Pwm_Isr_Pwm4(void);
    FN_IRQ_NOT_NESTED void Pwm_Isr_Pwm5(void);
    FN_IRQ_NOT_NESTED void Pwm_Isr_Pwm6(void);
    FN_IRQ_NOT_NESTED void Pwm_Isr_Pwm7(void);
    FN_IRQ_NOT_NESTED void Pwm_Isr_Pwm8(void);
    FN_IRQ_NOT_NESTED void Pwm_Isr_Pwm9(void);
    FN_IRQ_NOT_NESTED void Pwm_Isr_Pwm10(void);
    FN_IRQ_NOT_NESTED void Pwm_Isr_Pwm11(void);
    FN_IRQ_NOT_NESTED void Pwm_Isr_Pwm12(void);
    FN_IRQ_NOT_NESTED void Pwm_Isr_Pwm13(void);
    FN_IRQ_NOT_NESTED void Pwm_Isr_Pwm14(void);
    FN_IRQ_NOT_NESTED void Pwm_Isr_Pwm15(void);
    FN_IRQ_NOT_NESTED void Pwm_Isr_Pwm16(void);
    FN_IRQ_NOT_NESTED void Pwm_Isr_Pwm17(void);
    FN_IRQ_NOT_NESTED void Pwm_Isr_Pwm18(void);
    FN_IRQ_NOT_NESTED void Pwm_Isr_Pwm19(void);
    FN_IRQ_NOT_NESTED void Pwm_Isr_Pwm20(void);
    FN_IRQ_NOT_NESTED void Pwm_Isr_Pwm21(void);
    FN_IRQ_NOT_NESTED void Pwm_Isr_Pwm22(void);
    FN_IRQ_NOT_NESTED void Pwm_Isr_Pwm23(void);
    FN_IRQ_NOT_NESTED void Pwm_Isr_Pwm24(void);
    FN_IRQ_NOT_NESTED void Pwm_Isr_Pwm25(void);
    FN_IRQ_NOT_NESTED void Pwm_Isr_Pwm26(void);
    FN_IRQ_NOT_NESTED void Pwm_Isr_Pwm27(void);
    FN_IRQ_NOT_NESTED void Pwm_Isr_Pwm28(void);
    FN_IRQ_NOT_NESTED void Pwm_Isr_Pwm29(void);
    FN_IRQ_NOT_NESTED void Pwm_Isr_Pwm30(void);
    FN_IRQ_NOT_NESTED void Pwm_Isr_Pwm31(void);
    
    extern void Pwm_Config(uint8_t ch, uint16_t Cycle, uint16_t Duty);
    extern void Speed_Output_Pwm_Config(uint8_t ch, uint16_t Cycle, uint16_t Duty);
    extern void Speed_Output_Update(uint8_t ch, uint16_t Cycle, uint16_t Duty);
    extern void ILL_Output_PwmConfig(uint8_t ch, uint16_t Cycle, uint16_t Duty);
    extern void ILL_Output_Update(uint8_t ch, uint16_t Cycle, uint16_t Duty);
    
    extern uint8_t GetPwmStatus(uint8_t ch);

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