/******************************************************************************
�� �� ����PWM.h
����������PWM���ü�����ͷ�ļ�
��    �ߣ�����
��    ����V1.0
��    �ڣ�2016.11.3
******************************************************************************/

#ifndef _PWM_H_
#define _PWM_H_

#include "CRG.h"

/******************************************************************************
PWM����4�����õ�ʱ�ӣ�clock A, clock B, clock SA �� clock SB (scaled B), ��Щʱ
�Ӷ��ǻ�������ʱ��(BUSCLK)���ɵ�. clock A/B ֱ��������ʱ��(BUSCLK)��Ƶ�õ�,
clock SA/SB ������ clock A/B ��һ����Ƶ�õ�

PWMͨ�� 0 / 1 / 4 / 5 ����ѡ�� clock A / clock SA �е�һ����Ϊ��ʱ������
PWMͨ�� 2 / 3 / 6 / 7 ����ѡ�� clock B / clock SB �е�һ����Ϊ��ʱ������

����PWMͨ���������ѡ���ʱ������Ϊ����,�������ɸ��Բ�ͬƵ�ʡ���ͬ��λ����ͬռ
�ձȵ�PWM����
******************************************************************************/

/******************************************************************************
PWM Clock A/B Ƶ��ѡ��
******************************************************************************/
#define     PWM_CLKA_FREQ                  BUS_CLK_DIV_8
#define     PWM_CLKB_FREQ                  BUS_CLK_DIV_8
/******************************************************************************
PWM Clock A/B ��ѡƵ���б�
******************************************************************************/
#define     BUS_CLK_DIV_1                  0x00
#define     BUS_CLK_DIV_2                  0x01
#define     BUS_CLK_DIV_4                  0x02
#define     BUS_CLK_DIV_8                  0x03
#define     BUS_CLK_DIV_16                 0x04
#define     BUS_CLK_DIV_32                 0x05
#define     BUS_CLK_DIV_64                 0x06
#define     BUS_CLK_DIV_128                0x07

/******************************************************************************
PWM Clock SA/SB Ƶ������
*******************************************************************************
ע�⣺���õ�Clock SA/SBƵ��,�������������¹�ʽ�������ɵ�ֵ
Clock SA = Clock A / (2 * PWMSCLA)
Clock SB = Clock B / (2 * PWMSCLB)
******************************************************************************/
#define     PWM_CLKSA_FREQ                 10000
#define     PWM_CLKSB_FREQ                 2000000
/******************************************************************************
PWMͨ������ѡ��
******************************************************************************/
#define    PWM_POL_NGE                     0x00
#define    PWM_POL_POS                     (!PWM_POL_NGE)

/******************************************************************************
PWMͨ��ʱ��Դѡ��
******************************************************************************/
#define    PWM_CLOCK_A                     0x00
#define    PWM_CLOCK_SA                    (!PWM_CLOCK_A)

#define    PWM_CLOCK_B                     0x00
#define    PWM_CLOCK_SB                    (!PWM_CLOCK_B)

/******************************************************************************
PWMͨ�����뷽ʽ
******************************************************************************/
#define    PWM_LEFT_ALIGN                  0x00
#define    PWM_CENTER_ALIGN                (!PWM_LEFT_ALIGN )

/******************************************************************************
PWM����˿�ѡ��
******************************************************************************/
#define    PWM0_PP0                        0x00
#define    PWM0_PS4                        0x01

#define    PWM1_PP1                        0x00
#define    PWM1_PS5                        0x02

#define    PWM2_PP2                        0x00
#define    PWM2_PS6                        0x04

#define    PWM3_PP3                        0x00
#define    PWM3_PS7                        0x08

#define    PWM4_PP4                        0x00
#define    PWM4_PS2                        0x01
#define    PWM4_PV0                        0x02
#define    PWM4_PM0                        0x03

#define    PWM5_PP5                        0x00
#define    PWM5_PS3                        0x04
#define    PWM5_PV1                        0x08
#define    PWM5_PM1                        0x0C

#define    PWM6_PP6                        0x00
#define    PWM6_PS0                        0x10
#define    PWM6_PV2                        0x20
#define    PWM6_PM2                        0x30

#define    PWM7_PP7                        0x00
#define    PWM7_PS1                        0x40
#define    PWM7_PV3                        0x80
#define    PWM7_PM3                        0xC0

/******************************************************************************
PWM ʱ��Ƶ��Ԥ����
******************************************************************************/
#ifndef PWM_CLKA_FREQ
#error    Please define PWM_CLKA_FREQ in PWM.h
#endif

#if     (PWM_CLKA_FREQ == BUS_CLK_DIV_1)
#define   PWMCLKA                        BUSCLK
#elif   (PWM_CLKA_FREQ == BUS_CLK_DIV_2)
#define   PWMCLKA                        (BUSCLK / 2)
#elif   (PWM_CLKA_FREQ == BUS_CLK_DIV_4)
#define   PWMCLKA                        (BUSCLK / 4)
#elif   (PWM_CLKA_FREQ == BUS_CLK_DIV_8)
#define   PWMCLKA                        (BUSCLK / 8)
#elif   (PWM_CLKA_FREQ == BUS_CLK_DIV_16)
#define   PWMCLKA                        (BUSCLK / 16)
#elif   (PWM_CLKA_FREQ == BUS_CLK_DIV_32)
#define   PWMCLKA                        (BUSCLK / 32)
#elif   (PWM_CLKA_FREQ == BUS_CLK_DIV_64)
#define   PWMCLKA                        (BUSCLK / 64)
#elif   (PWM_CLKA_FREQ == BUS_CLK_DIV_128)
#define   PWMCLKA                        (BUSCLK / 128)
#else
#error    Please define PWM_CLKA_FREQ within a valid value range
#endif

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

#if    (PWM_CLKB_FREQ == BUS_CLK_DIV_1)
#define   PWMCLKB                        BUSCLK
#elif  (PWM_CLKB_FREQ == BUS_CLK_DIV_2)
#define   PWMCLKB                        (BUSCLK / 2)
#elif  (PWM_CLKB_FREQ == BUS_CLK_DIV_4)
#define   PWMCLKB                        (BUSCLK / 4)
#elif  (PWM_CLKB_FREQ == BUS_CLK_DIV_8)
#define   PWMCLKB                        (BUSCLK / 8)
#elif  (PWM_CLKB_FREQ == BUS_CLK_DIV_16)
#define   PWMCLKB                        (BUSCLK / 16)
#elif  (PWM_CLKB_FREQ == BUS_CLK_DIV_32)
#define   PWMCLKB                        (BUSCLK / 32)
#elif  (PWM_CLKB_FREQ == BUS_CLK_DIV_64)
#define   PWMCLKB                        (BUSCLK / 64)
#elif  (PWM_CLKB_FREQ == BUS_CLK_DIV_128)
#define   PWMCLKB                        (BUSCLK / 128)
#else
#error    Please define PWM_CLKB_FREQ within a valid value range
#endif

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

#if    (PWM_CLKSA_FREQ == 0)
#error Please define PWM_CLKSA_FREQ within a valid value range
#elif  (PWM_CLKSA_FREQ > PWMCLKA / 2)
#error Please define PWM_CLKSA_FREQ within a valid value range
#else
#if  (((PWMCLKA / 2) % PWM_CLKSA_FREQ == 0) && ((PWMCLKA / 2) / PWM_CLKSA_FREQ <= 256))
#define   PWMCLKSA                     PWM_CLKSA_FREQ
#if  ((PWMCLKA / 2) / PWM_CLKSA_FREQ == 256)
#define  PWMSCLAREG                  0x00
#else
#define  PWMSCLAREG                  (PWMCLKA / 2) / PWM_CLKSA_FREQ
#endif
#else
#error  Can not generate PWM_CLKSA_FREQ by current setting
#endif
#endif

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

#if    (PWM_CLKSB_FREQ == 0)
#error Please define PWM_CLKSB_FREQ within a valid value range
#elif  (PWM_CLKSB_FREQ > PWMCLKB / 2)
#error Please define PWM_CLKSB_FREQ within a valid value range
#else
#if  (((PWMCLKB / 2) % PWM_CLKSB_FREQ == 0) && ((PWMCLKB / 2) / PWM_CLKSB_FREQ <= 256))
#define   PWMCLKSB                     PWM_CLKSB_FREQ
#if  ((PWMCLKB / 2) / PWM_CLKSB_FREQ == 256)
#define  PWMSCLBREG                  0x00
#else
#define  PWMSCLBREG                  (PWMCLKB / 2) / PWM_CLKSB_FREQ
#endif
#else
#error  Can not generate PWM_CLKSB_FREQ by current setting
#endif
#endif

/******************************************************************************
��������
******************************************************************************/
void PWM_Init(void);
void PWM_Channel_Init(uint8_t Ch, uint8_t ClkSrc, uint8_t Pol, uint8_t Cae, uint8_t IOSel);
void PWM_Channel_Set_Freq(uint8_t Ch, uint32_t Freq);
void PWM_Channel_Set_Duty_Cycle(uint8_t Ch, uint8_t Dty);
void PWM_Channel_Start(uint8_t Ch);
void PWM_Channel_Stop(uint8_t Ch);

#endif