#ifndef _XHY_PWM_H_
#define _XHY_PWM_H_


typedef unsigned char INT8U;
typedef unsigned int INT16U;
typedef unsigned long INT32U;
//////////////////////固定参数///////////////////////////////////////////////////////////

//PWM各个通道选择引脚时用到的参数
typedef enum
{
  //PWM通道0 // 对应29引脚//端口PP0
  PWM_CH0_PIN29_PP0 = 0X00,
  PWM_CH0_PIN47_PS4 = 0X01,

  PWM_CH1_PIN30_PP1 = 0X10,
  PWM_CH1_PIN48_PS5 = 0X11,

  PWM_CH2_PIN31_PP2 = 0X20,
  PWM_CH2_PIN49_PS6 = 0X21,

  PWM_CH3_PIN32_PP3 = 0X30,
  PWM_CH3_PIN50_PS7 = 0X31,

  PWM_CH4_PIN33_PP4 = 0X40,
  PWM_CH4_PIN43_PS2 = 0X41,
  PWM_CH4_PIN19_PV0 = 0X42,
  PWM_CH4_PIN69_PM0 = 0X43,

  PWM_CH5_PIN34_PP5 = 0X50,
  PWM_CH5_PIN44_PS3 = 0X51,
  PWM_CH5_PIN20_PV1 = 0X52,
  PWM_CH5_PIN70_PM1 = 0X53,

  PWM_CH6_PIN35_PP6 = 0X60,
  PWM_CH6_PIN39_PS0 = 0X61,
  PWM_CH6_PIN21_PV2 = 0X62,
  PWM_CH6_PIN71_PM2 = 0X63,

  PWM_CH7_PIN36_PP7 = 0X70,
  PWM_CH7_PIN40_PS1 = 0X71,
  PWM_CH7_PIN22_PV3 = 0X72,
  PWM_CH7_PIN72_PM3 = 0X73,

} _PWMCHPIN_Type;
// PWM通道 0 / 1 / 4 / 5 可以选择 clock A / clock SA 中的一个作为其时钟输入
// PWM通道 2 / 3 / 6 / 7 可以选择 clock B / clock SB 中的一个作为其时钟输入
//PWM通道时钟源选择
typedef enum
{
  PWM_CLOCK_A = 0x00,
  PWM_CLOCK_SA,
  PWM_CLOCK_B,
  PWM_CLOCK_SB,

} _PWMClock_Select;
//PWM通道极性选择
typedef enum
{
  PWM_POL_NEG = 0x00,       //低电平
  PWM_POL_POS,                  //高电平
} _PWMPolarity_Select;
//PWM通道对齐模式选择
typedef enum
{
  PWM_LEFT_ALIGN = 0x00,
  PWM_CENTER_ALIGN,          
} _PWMAlign_Select;
//PWM时钟A B可选频率//默认总线频率32000000
#define PWM_CLOCK_Fre_32M 32000000
#define PWM_CLOCK_Fre_16M 16000000
#define PWM_CLOCK_Fre_8M 8000000
#define PWM_CLOCK_Fre_4M 4000000
#define PWM_CLOCK_Fre_2M 2000000
#define PWM_CLOCK_Fre_1M 1000000
#define PWM_CLOCK_Fre_500K 500000
#define PWM_CLOCK_Fre_250K 250000

///////////////////////////////////仅以下内容可修改///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////仅以下内容可修改///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////仅以下内容可修改///////////////////////////////////////////////////////////////////////////////////////////
//选择时钟源A  B的频率
#define PWM_CLOCK_A_FREQ PWM_CLOCK_Fre_1M
#define PWM_CLOCK_B_FREQ PWM_CLOCK_Fre_1M
//设置时钟源SA  SB的频率
// 注意：设置的Clock SA/SB频率,必须是依照如下公式可以生成的值
// Clock SA = Clock A / (2 * PWMSCLA) //PWMSCLA  范围1--256
// Clock SB = Clock B / (2 * PWMSCLB) //PWMSCLB  范围1--256
#define PWM_CLOCK_SA_FREQ 500000   //HZ
#define PWM_CLOCK_SB_FREQ 250000 //HZ

//通道 xx 是否开启级联  1开启   0关闭
#define  PWM_Channel_01_Cascade_Mode  0
#define  PWM_Channel_23_Cascade_Mode  0
#define  PWM_Channel_45_Cascade_Mode  0
#define  PWM_Channel_67_Cascade_Mode  0

//////////////////////仅以上内容可修改///////////////////////////////////////////////////////////////////////////////////
//////////////////////仅以上内容可修改///////////////////////////////////////////////////////////////////////////////////
//////////////////////仅以上内容可修改///////////////////////////////////////////////////////////////////////////////////

////////////////////////PWM 时钟频率预处理/////////////////////////////////////////////////////////

#ifndef PWM_CLOCK_A_FREQ
#error Please define PWM_CLOCK_A_FREQ in PWM.h
#endif

#if (PWM_CLOCK_A_FREQ == PWM_CLOCK_Fre_32M)
#define PWM_CLOCK_A_DIV 0x00
#elif (PWM_CLOCK_A_FREQ == PWM_CLOCK_Fre_16M)
#define PWM_CLOCK_A_DIV 0x01
#elif (PWM_CLOCK_A_FREQ == PWM_CLOCK_Fre_8M)
#define PWM_CLOCK_A_DIV 0x02
#elif (PWM_CLOCK_A_FREQ == PWM_CLOCK_Fre_4M)
#define PWM_CLOCK_A_DIV 0x03
#elif (PWM_CLOCK_A_FREQ == PWM_CLOCK_Fre_2M)
#define PWM_CLOCK_A_DIV 0x04
#elif (PWM_CLOCK_A_FREQ == PWM_CLOCK_Fre_1M)
#define PWM_CLOCK_A_DIV 0x05
#elif (PWM_CLOCK_A_FREQ == PWM_CLOCK_Fre_500K)
#define PWM_CLOCK_A_DIV 0x06
#elif (PWM_CLOCK_A_FREQ == PWM_CLOCK_Fre_250K)
#define PWM_CLOCK_A_DIV 0x07
#else
#error Please define PWM_CLOCK_A_FREQ within a valid value range
#endif

#ifndef PWM_CLOCK_B_FREQ
#error Please define PWM_CLOCK_B_FREQ in PWM.h
#endif

#if (PWM_CLOCK_B_FREQ == PWM_CLOCK_Fre_32M)
#define PWM_CLOCK_B_DIV 0x00     
#elif (PWM_CLOCK_B_FREQ == PWM_CLOCK_Fre_16M)
#define PWM_CLOCK_B_DIV 0x01
#elif (PWM_CLOCK_B_FREQ == PWM_CLOCK_Fre_8M)
#define PWM_CLOCK_B_DIV 0x02
#elif (PWM_CLOCK_B_FREQ == PWM_CLOCK_Fre_4M)
#define PWM_CLOCK_B_DIV 0x03
#elif (PWM_CLOCK_B_FREQ == PWM_CLOCK_Fre_2M)
#define PWM_CLOCK_B_DIV 0x04
#elif (PWM_CLOCK_B_FREQ == PWM_CLOCK_Fre_1M)
#define PWM_CLOCK_B_DIV 0x05
#elif (PWM_CLOCK_B_FREQ == PWM_CLOCK_Fre_500K)
#define PWM_CLOCK_B_DIV 0x06
#elif (PWM_CLOCK_B_FREQ == PWM_CLOCK_Fre_250K) 
#define PWM_CLOCK_B_DIV 0x07
#else  
#error Please define PWM_CLOCK_B_FREQ within a valid value range
#endif

#ifndef PWM_CLOCK_SA_FREQ
#error Please define PWM_CLOCK_SA_FREQ in PWM.h
#endif

#if (PWM_CLOCK_SA_FREQ == 0)
#error Please define PWM_CLOCK_SA_FREQ within a valid value range
#elif (PWM_CLOCK_SA_FREQ > PWM_CLOCK_A_FREQ / 2)
#error Please define PWM_CLOCK_SA_FREQ within a valid value range
#else
#if (((PWM_CLOCK_A_FREQ / 2) % PWM_CLOCK_SA_FREQ == 0) && ((PWM_CLOCK_A_FREQ / 2) / PWM_CLOCK_SA_FREQ <= 256))
#define PWM_CLOCK_SA_Real_FREQ PWM_CLOCK_SA_FREQ //其实可不用
#if ((PWM_CLOCK_A_FREQ / 2) / PWM_CLOCK_SA_FREQ == 256)
#define PWMSCLAREG 0x00
#else
#define PWMSCLAREG (PWM_CLOCK_A_FREQ / 2) / PWM_CLOCK_SA_FREQ
#endif
#else
#error Cannot generate PWM_CLOCK_SA_FREQ by current setting
#endif
#endif


#ifndef PWM_CLOCK_SB_FREQ
#error Please define PWM_CLOCK_SB_FREQ in PWM.h
#endif

#if (PWM_CLOCK_SB_FREQ == 0)
#error Please define PWM_CLOCK_SB_FREQ within a valid value range
#elif (PWM_CLOCK_SB_FREQ > PWM_CLOCK_B_FREQ / 2)
#error Please define PWM_CLOCK_SB_FREQ within a valid value range
#else
#if (((PWM_CLOCK_B_FREQ / 2) % PWM_CLOCK_SB_FREQ == 0) && ((PWM_CLOCK_B_FREQ / 2) / PWM_CLOCK_SB_FREQ <= 256))
#define PWM_CLOCK_SB_Real_FREQ PWM_CLOCK_SB_FREQ
#if ((PWM_CLOCK_B_FREQ / 2) / PWM_CLOCK_SB_FREQ == 256)
#define PWMSCLBREG 0x00
#else
#define PWMSCLBREG (PWM_CLOCK_B_FREQ / 2) / PWM_CLOCK_SB_FREQ
#endif
#else
#error Cannot generate PWM_CLOCK_SB_FREQ by current setting
#endif
#endif


////////////////////////函数声明/////////////////////////////////////////////////////////
extern void PWM_Init(void);
extern void PWM_Channel_Init(_PWMCHPIN_Type Pin, _PWMClock_Select ClkSrc, _PWMPolarity_Select Pol, _PWMAlign_Select Cae);

extern void PWM_Channel_Set_Freq(_PWMCHPIN_Type Pin, INT32U Freq);
extern void PWM_Channel_Set_Duty(_PWMCHPIN_Type Pin, INT8U Dty);    
extern void PWM_Channel_Enable(_PWMCHPIN_Type Pin, INT8U Onoff);
extern void PWM_Channel_Cascade_Set_Freq(_PWMCHPIN_Type Pin, INT32U Freq);
extern void PWM_Channel_Cascade_Set_Duty(_PWMCHPIN_Type Pin, INT8U Dty);

extern void  PWM_Wake_Up_Init(void);
extern void  PWM_Sleep_Init(void);


#endif