/**
 * \file    drv_pwm.h
 * \brief   
 * 
 * \par     Copyright (c) 2018 UWE Technologies Corp., Ltd. All Rights Reserved.
 * \author  James
 * \date    2018-03-21
 * \version 
 * 
 * \history 
 *  Date        Note
 *  2018-03-21  Original Creation
 * 
 */
 
#ifndef __DRV_PWM_H_
#define __DRV_PWM_H_

#include "types.h"
#include "drv_reg_intf.h"
#include "reg_def_pwm.h"


#pragma pack(1)

typedef enum drv_pwm_chn_e 
{
    DRV_PWM_CHN_0,
    DRV_PWM_CHN_1,
    DRV_PWM_CHN_2,
    DRV_PWM_CHN_3,
    DRV_PWM_CHN_4,
    DRV_PWM_CHN_5,
    DRV_PWM_CHN_MAX
} drv_pwm_chn_t;

#pragma pack()


/**
 * Get PWM enable state function
 *
 * \param id        PWM index
 * \return          Enabled(expressions==true) or disabled(expressions==false)
 *
 * \see
 */
#define drv_pwm_en_get(id)     (SAL_IS_BIT_SET(DRV_REG_GET(PWM_EN_REG),(id)))

/**
 * Enable/disable PWM function
 *
 * \param id        PWM index
 * \param flg       Enable(1) or disable(0)
 *
 * \see
 */
#define drv_pwm_en_set(id,flg)     drv_reg_field_set(PWM_EN_REG,(id),1,(flg))

/**
 * Enable/disable PWM Pair function
 *
 * \param id1        PWM index 1
 * \param id2        PWM index 2
 * \param flg       Enable(1) or disable(0)
 *
 * \see
 */
void drv_pwm_en_pair_set(int id1, int id2, bool_t flg);


/**
 * Configure PWM initial value and PER
 *
 * \param id        PWM index, valid range: 0 ~ 5
 * \param high      Waveform initial value, 1'b1 : start as high; 1'b0 : start as low.
 * \param per       Waveform period 
 *
 */
#define drv_pwm_init_set(id,high,per) \
    do { \
        DRV_REG_SET(PWM0_CFG_REG_0+8*(id), ((high) << PWM0_CFG_REG_0_PWM_INIT_VAL) | (per)); \
    } while(0)

/**
 * Get PWM initial value
 *
 * \param id        PWM index, valid range: 0 ~ 5
 *
 */
#define drv_pwm_init_get(id)        ((DRV_REG_GET(PWM0_CFG_REG_0+8*(id))&PWM0_CFG_REG_0_PWM_INIT_VAL_FLDSET)>>PWM0_CFG_REG_0_PWM_INIT_VAL)

/**
 * Get PWM waveform period
 *
 * \param id        PWM index, valid range: 0 ~ 5
 *
 */
#define drv_pwm_per_get(id)        (DRV_REG_GET(PWM0_CFG_REG_0+8*(id))&PWM0_CFG_REG_0_PWM_PER_FLDSET)


/**
 * Configure PWM duty cycle via two comparation values, counter compare point 1 
 * must less than counter compare point 2, compare points must less than period
 *
 * \param id        PWM index, valid range: 0 ~ 5
 * \param cmp1      Counter compare point 1, when counter equal to this compare point value, the output is toggled
 * \param cmp2      Counter compare point 2, when counter equal to this compare point value, the output is toggled
 *
 */
void drv_pwm_duty_set(int id, u32_t cmp1, u32_t cmp2);

/**
 * Configure PWM duty cycle via two comparation values
 *
 * \param id        PWM index, valid range: 0 ~ 5
 * \param dutyVal   Duty value, combine with Counter compare point 1 and 2, when counter equal to the compare point values, the output is toggled
 *
 */
#define drv_pwm_duty_set2(id,dutyVal) \
    do { \
        DRV_REG_SET(PWM0_CFG_REG_1+8*(id), dutyVal); \
    } while(0)

/**
 * Get PWM duty cycle 
 *
 * \param id        PWM index, valid range: 0 ~ 5
 *
 */
#define drv_pwm_duty_get(id)        DRV_REG_GET(PWM0_CFG_REG_1+8*(id))

/**
 * Get PWM compare point 1 of duty cycle 
 *
 * \param id        PWM index, valid range: 0 ~ 5
 *
 */
#define drv_pwm_duty_cmp1_get(id)   ((DRV_REG_GET(PWM0_CFG_REG_1+8*(id)) & PWM0_CFG_REG_1_PWM_CMP_1_FLDSET) >> PWM0_CFG_REG_1_PWM_CMP_1)

/**
 * Get PWM compare point 2 of duty cycle 
 *
 * \param id        PWM index, valid range: 0 ~ 5
 *
 */
#define drv_pwm_duty_cmp2_get(id)   (DRV_REG_GET(PWM0_CFG_REG_1+8*(id)) & PWM0_CFG_REG_1_PWM_CMP_2_FLDSET)


/**
 * Configure PWM initial value, PER and compare value
 *
 * \param id        PWM index
 * \param init_high Waveform initial value, 1'b1 : start as high; 1'b0 : start as low.
 * \param per       Waveform period 
 * \param cmp1      Counter compare point 1, when counter equal to this compare point value, the output is toggled
 * \param cmp2      Counter compare point 2, when counter equal to this compare point value, the output is toggled
 *
 * \see
 */
void drv_pwm_set(int id, bool_t init_high, u16_t per, u16_t cmp1, u16_t cmp2);

/**
 * Configure PWM initial value, Frequency and Duty value
 *
 * \param id        PWM index
 * \param init_high Waveform initial value, 1'b1 : start as high; 1'b0 : start as low.
 * \param freq      PWM frequency, must <= 33000000 Hz
 * \param duty      Duty cycle
 *
 * \see
 */
void drv_pwm_freq_set(int id, bool_t init_high, u32_t freq, u32_t duty);

/**
 * Configure PWM duty value
 *
 * \param id        PWM index
 * \param duty      Duty cycle: 0 - 100
 *
 * \see
 */
void drv_pwm_duty_set3(int id, u32_t duty);


#endif /* #ifndef __DRV_PWM_H_ */


