/**************************************************************************************************
*******
**************************************************************************************************/

/*******************************************************************************
    @file     pwm.h
    @brief    Contains all functions support for pwm driver
    @version  0.0
    @date     30. Oct. 2017
    @author   Ding



*******************************************************************************/
#ifndef __PWM__H__
#define __PWM__H__

#ifdef __cplusplus
extern "C" {
#endif

#include "types.h"
#include "gpio.h"


#define    PWM_ENABLE_ALL               do{\
        AP_PWM->pwmen |= BIT(0);\
        AP_PWM->pwmen |= BIT(4);\
    }while(0)
#define    PWM_DISABLE_ALL              do{\
        AP_PWM->pwmen &= ~BIT(0);\
        AP_PWM->pwmen &= ~BIT(4);\
    }while(0)
#define    PWM_ENABLE_CH_012            do{\
        AP_PWM->pwmen |= BIT(8);\
        AP_PWM->pwmen |= BIT(9);\
    }while(0)
#define    PWM_DISABLE_CH_012           do{\
        AP_PWM->pwmen &= ~BIT(8);\
        AP_PWM->pwmen &= ~BIT(9);\
    }while(0)
#define    PWM_ENABLE_CH_345            do{\
        AP_PWM->pwmen |= BIT(10);\
        AP_PWM->pwmen |= BIT(11);\
    }while(0)
#define    PWM_DISABLE_CH_345           do{\
        AP_PWM->pwmen &= ~BIT(10);\
        AP_PWM->pwmen &= ~BIT(11);\
    }while(0)
#define    PWM_ENABLE_CH_01             do{\
        AP_PWM->pwmen |= BIT(12);\
        AP_PWM->pwmen |= BIT(13);\
    }while(0)
#define    PWM_DISABLE_CH_01            do{\
        AP_PWM->pwmen &= ~BIT(12);\
        AP_PWM->pwmen &= ~BIT(13);\
    }while(0)
#define    PWM_ENABLE_CH_23             do{\
        AP_PWM->pwmen |= BIT(14);\
        AP_PWM->pwmen |= BIT(15);\
    }while(0)
#define    PWM_DISABLE_CH_23            do{\
        AP_PWM->pwmen &= ~BIT(14);\
        AP_PWM->pwmen &= ~BIT(15);\
    }while(0)
#define    PWM_ENABLE_CH_45             do{\
        AP_PWM->pwmen |= BIT(16);\
        AP_PWM->pwmen |= BIT(17);\
    }while(0)
#define    PWM_DISABLE_CH_45            do{\
        AP_PWM->pwmen &= ~BIT(16);\
        AP_PWM->pwmen &= ~BIT(17);\
    }while(0)

#define    PWM_INSTANT_LOAD_CH(n)       subWriteReg(&(AP_PWM_CTRL(n)->ctrl0),31,31,1)
#define    PWM_NO_INSTANT_LOAD_CH(n)    subWriteReg(&(AP_PWM_CTRL(n)->ctrl0),31,31,0)
#define    PWM_LOAD_CH(n)               subWriteReg(&(AP_PWM_CTRL(n)->ctrl0),16,16,1)
#define    PWM_NO_LOAD_CH(n)            subWriteReg(&(AP_PWM_CTRL(n)->ctrl0),16,16,0)
#define    PWM_SET_DIV(n,v)             subWriteReg(&(AP_PWM_CTRL(n)->ctrl0),14,12,v)
#define    PWM_SET_MODE(n,v)            subWriteReg(&(AP_PWM_CTRL(n)->ctrl0),8,8,v)
#define    PWM_SET_POL(n,v)             subWriteReg(&(AP_PWM_CTRL(n)->ctrl0),4,4,v)
#define    PWM_ENABLE_CH(n)             subWriteReg(&(AP_PWM_CTRL(n)->ctrl0),0,0,1)
#define    PWM_DISABLE_CH(n)            subWriteReg(&(AP_PWM_CTRL(n)->ctrl0),0,0,0)

#define    PWM_SET_CMP_VAL(n,v)         subWriteReg(&(AP_PWM_CTRL(n)->ctrl1),31,16,v)
#define    PWM_SET_TOP_VAL(n,v)         subWriteReg(&(AP_PWM_CTRL(n)->ctrl1),15,0,v)
#define    PWM_GET_CMP_VAL(n)           ((AP_PWM_CTRL(n)->ctrl1 & 0xFFFF0000) >> 8)
#define    PWM_GET_TOP_VAL(n)           AP_PWM_CTRL(n)->ctrl1 & 0x0000FFFF


/*************************************************************
    @brief      enum variable, the number of PWM channels supported

*/
typedef enum
{
    PWM_CH0 = 0,
    PWM_CH1 = 1,
    PWM_CH2 = 2,
    PWM_CH3 = 3,
    PWM_CH4 = 4,
    PWM_CH5 = 5
} PWMN_e;

/*************************************************************
    @brief      enum variable used for PWM clock prescaler

*/
typedef enum
{
    PWM_CLK_NO_DIV = 0,
    PWM_CLK_DIV_2 = 1,
    PWM_CLK_DIV_4 = 2,
    PWM_CLK_DIV_8 = 3,
    PWM_CLK_DIV_16 = 4,
    PWM_CLK_DIV_32 = 5,
    PWM_CLK_DIV_64 = 6,
    PWM_CLK_DIV_128 = 7
} PWM_CLK_DIV_e;

/*************************************************************
    @brief      enum variable used for PWM work mode setting

*/
typedef enum
{
    PWM_CNT_UP = 0,
    PWM_CNT_UP_AND_DOWN = 1
} PWM_CNT_MODE_e;

/*************************************************************
    @brief      enum variable used for PWM output polarity setting

*/
typedef enum
{
    PWM_POLARITY_RISING = 0,
    PWM_POLARITY_FALLING = 1
} PWM_POLARITY_e;

/**************************************************************************************
    @fn          hal_pwm_init

    @brief       This function process for pwm initial

    input parameters

    @param       PWMN_e pwmN                     : pwm channel
                PWM_CLK_DIV_e pwmDiv            : clock prescaler of PWM channel
                PWM_CNT_MODE_e pwmMode          : count mode of PWM channel
                PWM_POLARITY_e pwmPolarity      : output polarity setting of PWM channel
                unsigned short cmpVal           : the compare value of PWM channel
                unsigned short cntTopVal        : the counter top value of PWM channel

    output parameters

    @param       None.

    @return      None.
 **************************************************************************************/
void hal_pwm_init(PWMN_e pwmN, PWM_CLK_DIV_e pwmDiv,
                  PWM_CNT_MODE_e pwmMode, PWM_POLARITY_e pwmPolarity);

/**************************************************************************************
    @fn          hal_pwm_open_channel

    @brief       This function process for pwm start working

    input parameters

    @param       PWMN_e pwmN                     : pwm channel
                gpio_pin_e pwmPin               : pwm pin number

    output parameters

    @param       None.

    @return      None.
 **************************************************************************************/
void hal_pwm_open_channel(PWMN_e pwmN,gpio_pin_e pwmPin);

/**************************************************************************************
    @fn          hal_pwm_close_channel

    @brief       This function process for pwm stop working

    input parameters

    @param       PWMN_e pwmN                     : pwm channel

    output parameters

    @param       None.

    @return      None.
 **************************************************************************************/
void hal_pwm_close_channel(PWMN_e pwmN);

/**************************************************************************************
    @fn          hal_pwm_destroy

    @brief       This function process for pwm clear and disable

    input parameters

    @param       PWMN_e pwmN                     : pwm channel

    output parameters

    @param       None.

    @return      None.
 **************************************************************************************/
void hal_pwm_destroy(PWMN_e pwmN);

/**************************************************************************************
    @fn          hal_pwm_set_count_val

    @brief       This function process for change pwm count value

    input parameters

    @param       PWMN_e pwmN                     : pwm channel
                uint16_t cmpVal                 : the compare value of PWM channel
                uint16_t cntTopVal              : the counter top value of PWM channel

    output parameters

    @param       None.

    @return      None.
 **************************************************************************************/
void hal_pwm_set_count_val(PWMN_e pwmN, uint16_t cmpVal, uint16_t cntTopVal);

/**************************************************************************************
    @fn          hal_pwm_start

    @brief       pwm start

    input parameters

    @param       None.

    output parameters

    @param       None.

    @return      None.
 **************************************************************************************/
void hal_pwm_start(void);

/**************************************************************************************
    @fn          hal_pwm_stop

    @brief       pwm stop

    input parameters

    @param       None.

    output parameters

    @param       None.

    @return      None.
 **************************************************************************************/
void hal_pwm_stop(void);

//new api,make use easily
typedef struct
{
    PWMN_e pwmN;
    gpio_pin_e pwmPin;
    PWM_CLK_DIV_e pwmDiv;
    PWM_CNT_MODE_e pwmMode;
    PWM_POLARITY_e pwmPolarity;
    uint16_t cmpVal;
    uint16_t cntTopVal;

} pwm_ch_t;

/**************************************************************************************
    @fn          hal_pwm_module_init

    @brief       init pwm global variables

    input parameters

    @param       None.

    output parameters

    @param       None.

    @return      None.
 **************************************************************************************/
void hal_pwm_module_init(void);

/**************************************************************************************
    @fn          hal_pwm_module_deinit

    @brief       deinit pwm global variables

    input parameters

    @param       None.

    output parameters

    @param       None.

    @return      None.
 **************************************************************************************/
void hal_pwm_module_deinit(void);

/**************************************************************************************
    @fn          hal_pwm_ch_start

    @brief       config and make a pwm start to work

    input parameters

    @param       pwm_ch_t ch: pwm channel

    output parameters

    @param       None.

    @return      None.
 **************************************************************************************/
void hal_pwm_ch_start(pwm_ch_t ch);

/**************************************************************************************
    @fn          hal_pwm_ch_stop

    @brief       make a pwm stop form working

    input parameters

    @param       pwm_ch_t ch: pwm channel

    output parameters

    @param       None.

    @return      None.
 **************************************************************************************/
void hal_pwm_ch_stop(pwm_ch_t ch);

#ifdef __cplusplus
}
#endif


#endif
