#ifndef _PWM_H__
#define _PWM_H__
#include "bsp/bsp.h"
#include "os/os_types.h"

#define TIMER_CHCTL2_CH0EN               BIT(0)              /*!< channel 0 capture/compare function enable */
#define TIMER_CHCTL2_CH0P                BIT(1)              /*!< channel 0 capture/compare function polarity */
#define TIMER_CHCTL2_CH0NEN              BIT(2)              /*!< channel 0 complementary output enable */
#define TIMER_CHCTL2_CH0NP               BIT(3)              /*!< channel 0 complementary output polarity */
#define TIMER_CHCTL2_CH1EN               BIT(4)              /*!< channel 1 capture/compare function enable  */
#define TIMER_CHCTL2_CH1P                BIT(5)              /*!< channel 1 capture/compare function polarity */
#define TIMER_CHCTL2_CH1NEN              BIT(6)              /*!< channel 1 complementary output enable */
#define TIMER_CHCTL2_CH1NP               BIT(7)              /*!< channel 1 complementary output polarity */
#define TIMER_CHCTL2_CH2EN               BIT(8)              /*!< channel 2 capture/compare function enable  */
#define TIMER_CHCTL2_CH2P                BIT(9)              /*!< channel 2 capture/compare function polarity */
#define TIMER_CHCTL2_CH2NEN              BIT(10)             /*!< channel 2 complementary output enable */
#define TIMER_CHCTL2_CH2NP               BIT(11)             /*!< channel 2 complementary output polarity */


#define TIMxCCER_MASK_CH012        ((uint16_t)  (TIMER_CHCTL2_CH0EN|TIMER_CHCTL2_CH0NEN|\
                                                 TIMER_CHCTL2_CH1EN|TIMER_CHCTL2_CH1NEN|\
                                                 TIMER_CHCTL2_CH2EN|TIMER_CHCTL2_CH2NEN))
#define TIMxCCER_MASK_CP           ((uint16_t) TIMER_CHCTL2_CH0NP | TIMER_CHCTL2_CH1NP |TIMER_CHCTL2_CH2NP)
#define pwm_enable_channel() {MOS_PWM_TIMER->cctrl |= TIMxCCER_MASK_CH012;}
#define pwm_disable_channel() {MOS_PWM_TIMER->cctrl &= ~TIMxCCER_MASK_CH012;}


#define ch0_update_duty(duty) 	MOS_PWM_TIMER->c1dt = (uint32_t)duty
#define ch1_update_duty(duty) 	MOS_PWM_TIMER->c2dt = (uint32_t)duty
#define ch2_update_duty(duty) 	MOS_PWM_TIMER->c3dt = (uint32_t)duty
#define update_adc_trigger(time) MOS_PWM_TIMER->c4dt = (uint32_t)time

#ifdef CONFIG_PWM_UV_SWAP
#define pwm_update_duty(dutyA, dutyB, dutyC) \
	do {\
		ch0_update_duty(dutyC);\
		ch1_update_duty(dutyB);\
		ch2_update_duty(dutyA);\
	}while(0)

#else
#define pwm_update_duty(dutyA, dutyB, dutyC) \
	do {\
		ch0_update_duty(dutyA);\
		ch1_update_duty(dutyB);\
		ch2_update_duty(dutyC);\
	}while(0)

#endif

#define pwm_update_2smaples(samp1, sampl2) \
	do { \
		MOS_PWM_TIMER->c4dt = (uint32_t)samp1; \
	}while(0)


#define pwm_clear_updata() \
	tmr_flag_clear(MOS_PWM_TIMER, TMR_OVF_INT);

#define pwm_wait_and_clear_updata() \
	do { \
		while ( tmr_flag_get(MOS_PWM_TIMER, TMR_OVF_INT) == RESET ); \
		timer_flag_clear(MOS_PWM_TIMER, TMR_OVF_INT); \
	}while(0)

#define pwm_change_t3_mode(m) \
	do { \
		if (MOS_PWM_TIMER->cm2_output_bit.c4octrl != m) { \
			MOS_PWM_TIMER->cm2_output_bit.c4octrl = m; \
		} \
	}while(0)

#define pwm_brake_enable(n) \
	do { \
		if (n) { \
			nvic_irq_enable(TMR1_BRK_TMR9_IRQn, EBREAK_IRQ_PRIORITY, 0); \
		}else { \
			nvic_irq_disable(TMR1_BRK_TMR9_IRQn); \
		} \
	}while(0)

#define pwm_up_enable(n) \
	do { \
		if (n) { \
			tmr_flag_clear(MOS_PWM_TIMER, TMR_OVF_INT); \
			tmr_interrupt_enable(MOS_PWM_TIMER, TMR_OVF_INT, TRUE); \
		}else { \
			tmr_flag_clear(MOS_PWM_TIMER, TMR_OVF_INT); \
			tmr_interrupt_enable(MOS_PWM_TIMER, TMR_OVF_INT, FALSE); \
		} \
	}while(0)

#define get_deadtime() (MOS_PWM_TIMER->brk_bit.dtc)

void pwm_3phase_init(void);
void pwm_3phase_sides(bool hon, bool lon);
void pwm_start(void);
void pwm_stop(void);
void pwm_turn_on_low_side(void);
void pwm_enable_output(bool enable);
void pwm_update_sample(u32 samp1, u32 samp2, u8 sector);

#endif  /*_PWM_H__*/

