/*****************************************************************************
 *   hhd_pwm.h:  Header file for HHD32F0xx Microprocessors
 *
 *   Copyright(C) 2015, Ltd.
 *   All rights reserved.
 *
 *   History
 *   2015  ver 1.00    Prelimnary version, first Release
 *
******************************************************************************/

#ifndef __PWM_H 
#define __PWM_H
#include "hhd32f0xx.h"

//--PWM Registers BITS Field---------------------------------------------------------------------------------------
struct PWM_CTRL_BITS	{
			uint32_t PWMEN:1;	//This R/W bit enables the PWM generator. 
			uint32_t LDOK:1;	//This R/W bit loads the prescaler bits of CTRL and the entire CMOD and VALm registers into a set of buffers. The buffered prescaler divisor, PWM counter modulus value, and PWM pulse width take effect at the next PWM reload. Set LDOK by reading it, then write a Logic 1 to it. LDOK is automatically cleared after the new values are loaded, or can be manually cleared before a reload by writing a Logic 0 to it.
			uint32_t PWMF:1;	//This R/W flag is set at the beginning of every reload cycle regardless of the state of the LDOK bit. Clear PWMF by reading it, and then write a Logic 0 to it. If another reload occurs before the clearing sequence is complete, writing Logic 0 to the PWMF has no effect.
			uint32_t PWMRIE:1;	//This R/W bit enables the PWMF flag to generate interrupt request.
			uint32_t RSVD0:1;
			uint32_t PRSC:2;	//WM Clock Frequency. 
			uint32_t IPOL0:1;	//Select the PWM value register for the PWM_0 and PWM_1 pins pair in complementary mode. 
			uint32_t IPOL1:1;	//Select the PWM value register for the PWM_2 and PWM_3 pins pair in complementary mode.
			uint32_t IPOL2:1;	//Select the PWM value register for the PWM_4 and PWM_5 pins pair in complementary mode.
			uint32_t RSVD1:1;
			uint32_t HALF:1;	//Enable half-cycle reloads in Center-Aligned PWM mode. This bit has no effect on Edge-Aligned PWMs.
			uint32_t LDFQ:4;	//These buffered R/W bits select the PWM load frequency. Reset clears the LDFQ bit field, selecting loading every PWM opportunity. The occurrence of a PWM opportunity is determined by the half bit.
			uint32_t SOFTFAULT:1;	//This bit can trigger a software fault to the PWM Fault protect mode
			uint32_t INIDIR:1;	//Select initial count direction in center align mode
			uint32_t RSVD2:2;
			uint32_t TSCNT:2;	//Trig signal output count register. This field can determine the interval between each output trig signal
			uint32_t TSSEL:2;	//Trig signal select register. The output trig signal will be send to ADC and Timer.
			uint32_t CH0OUTEN:1;	//Output a signal when counter register of channel 0 equals to VAL0 
			uint32_t CH1OUTEN:1;	//Output a signal when counter register of channel 1 equals to VAL1 
			uint32_t CH2OUTEN:1;	//Output a signal when counter register of channel 2 equals to VAL2 
			uint32_t CH3OUTEN:1;	//Output a signal when counter register of channel 3 equals to VAL3 
			uint32_t CH4OUTEN:1;	//Output a signal when counter register of channel 4 equals to VAL4 
			uint32_t CH5OUTEN:1;	//Output a signal when counter register of channel 5 equals to VAL5 
			uint32_t RSVD3:2;	// 
};
union PWM_CTRL_REG {
				uint32_t				all;
				struct  PWM_CTRL_BITS		bit;
};
struct PWM_FCTRL_BITS	{
			uint32_t FMODE0:1;	//Select automatic or manual clearing of FAULT0 pin faults.
			uint32_t FIE0:1;	//Enable the interrupt request generated by the PWM_FAULT0 pin. 
			uint32_t FMODE1:1;	//Select automatic or manual clearing of Software faults.
			uint32_t FIE1:1;	//Enable the interrupt request generated by the Software fault. 
			uint32_t FMODE2:1;	//Select automatic or manual clearing of ADC limit faults
			uint32_t FIE2:1;	//Enable the interrupt request generated by the ADC limit fault.
			uint32_t RSVD3:26;	// 
};
union PWM_FCTRL_REG {
				uint32_t				all;
				struct  PWM_FCTRL_BITS		bit;
};
struct PWM_FLTACK_BITS	{
uint32_t FTACK0:1;	//Writing a Logic 1 to FTACK0 clears FFLAG0. 
uint32_t FTACK1:1;	//Writing a Logic 1 to FTACK1 clears FFLAG1. 
uint32_t FTACK2:1;	//Writing a Logic 1 to FTACK2 clears FFLAG2. 
uint32_t RSVD0:13;
uint32_t FFLAG0:1;	//These read-only flags are set within two PWM Operation Clock cycles after a rising edge on the PWM_FAULT0 pin. Clear FFLAG0 by writing a Logic 1 to the FTACK0 bits in the FLTACK register.
uint32_t FPIN0:1;	//These read-only bits reflect the current state of the filtered PWM_FAULT pin. A reset has no effect on FPIN0
uint32_t FFLAG1:1;	//These flags are set by software. Clear FFLAG6 by writing a Logic 1 to the FTACK6 bits in the FLTACK register.
uint32_t RSVD1:1;
uint32_t FFLAG2:1;	//This read-only flags are set within two PWM Operation Clock cycles after the ADC limit l fault happened. Clear FFLAG7 by writing a Logic 1 to the FTACK7 bits in the FLTACK register.
uint32_t FPIN2:1;	//This read-only bit reflect the current ADC limit state.
uint32_t RSVD3:10;
};
union PWM_FLTACK_REG {
				uint32_t				all;
				struct  PWM_FLTACK_BITS		bit;
};
struct PWM_OUTCTRL_BITS	{
			uint32_t OUT0:1;	//PWM_0 control
			uint32_t OUT1:1;	//PWM_1 control
			uint32_t OUT2:1;	//PWM_2 control
			uint32_t OUT3:1;	//PWM_3 control
			uint32_t OUT4:1;	//PWM_4 control
			uint32_t OUT5:1;	//PWM_5 control
			uint32_t RSVD0:2;
			uint32_t OUTCTL0:1;	//Software control enable to PWM_0 
			uint32_t OUTCTL1:1;	//Software control enable to PWM_1
			uint32_t OUTCTL2:1;	//Software control enable to PWM_2
			uint32_t OUTCTL3:1;	//Software control enable to PWM_3
			uint32_t OUTCTL4:1;	//Software control enable to PWM_4
			uint32_t OUTCTL5:1;	//Software control enable to PWM_5
			uint32_t RSVD1:18;	// 
};
union PWM_OUTCTRL_REG {
				uint32_t				all;
				struct  PWM_OUTCTRL_BITS		bit;
};
struct PWM_CNTR_BITS	{
			uint32_t CNT:16;	//This field displays the state of the 16-bit PWM counter.
			uint32_t RSVD:16;	// 
};
union PWM_CNTR_REG {
				uint32_t				all;
				struct  PWM_CNTR_BITS		bit;
};
struct PWM_CMOD_BITS	{
			uint32_t CM:16;	//PWM period in the PWM clock periods.
			uint32_t RSVD:16;	// 
};
union PWM_CMOD_REG {
				uint32_t				all;
				struct  PWM_CMOD_BITS		bit;
};
struct PWM_VAL_BITS	{
			uint32_t VAL:16;	//The PWM Value registers
			uint32_t RSVD:16;	// 
};
union PWM_VAL_REG {
				uint32_t				all;
				struct  PWM_VAL_BITS		bit;
};
struct PWM_DTIM_BITS	{
			uint32_t DTIM:16;	//PWM Deadtime Registers
			uint32_t RSVD:16;	// 
};
union PWM_DTIM_REG {
				uint32_t				all;
				struct  PWM_DTIM_BITS		bit;
};
struct PWM_DMAP0_BITS	{
				uint32_t P0FLTMAP0:1;	//This bit enables Fault pin 0 to protect PWM pin 0 output
				uint32_t P0FLTMAP1:1;	//This bit enables Software Fault to protect PWM pin 0 output
				uint32_t P0FLTMAP2:1;	//This bit enables ADC out of limit to protect PWM pin 0 output
				uint32_t RSVD0:5;	
				uint32_t P1FLTMAP0:1;	//This bit enables Fault pin 0 to protect PWM pin 1 output
				uint32_t P1FLTMAP1:1;	//This bit enables Software Fault to protect PWM pin 1 output
				uint32_t P1FLTMAP2:1;	//This bit enables ADC out of limit to protect PWM pin 1 output
				uint32_t RSVD1:5;
				uint32_t P2FLTMAP0:1;	//This bit enables Fault pin 0 to protect PWM pin 2 output
				uint32_t P2FLTMAP1:1;	//This bit enables Software Fault to protect PWM pin 2 output
				uint32_t P2FLTMAP2:1;	//This bit enables ADC out of limit to protect PWM pin 2 output
				uint32_t RSVD2:5;
				uint32_t P3FLTMAP0:1;	//This bit enables Fault pin 0 to protect PWM pin 3 output
				uint32_t P3FLTMAP1:1;	//This bit enables Software Fault to protect PWM pin 3 output
				uint32_t P3FLTMAP2:1;	//This bit enables ADC out of limit to protect PWM pin 3 output
				uint32_t RSVD3:5;	
};
union PWM_DMAP0_REG {
				uint32_t				all;
				struct  PWM_DMAP0_BITS		bit;
};
struct PWM_DMAP1_BITS	{
uint32_t P4FLTMAP0:1;	//This bit enables Fault pin 0 to protect PWM pin 4 output
uint32_t P4FLTMAP1:1;	//This bit enables Software Fault to protect PWM pin 4 output
uint32_t P4FLTMAP2:1;	//This bit enables ADC out of limit to protect PWM pin 4 output
uint32_t RSVD0:5;	
uint32_t P5FLTMAP0:1;	//This bit enables Fault pin 0 to protect PWM pin 5 output
uint32_t P5FLTMAP1:1;	//This bit enables Software Fault to protect PWM pin 5 output
uint32_t P5FLTMAP2:1;	//This bit enables ADC out of limit to protect PWM pin 5 output
uint32_t RSVD1:21;
};
union PWM_DMAP1_REG {
				uint32_t				all;
				struct  PWM_DMAP1_BITS		bit;
};
struct PWM_CNFG_BITS	{
				uint32_t WP:1;	//This bit enables write-protection for all write-protectable registers. 
				uint32_t NDEP01:1;	//This write-protectable bit determines if the PWM Channel 0-1 will be independent PWMs or complementary PWM pairs.
				uint32_t NDEP23:1;	//This write-protectable bit determines if the PWM Channel 2-3 will be independent PWMs or complementary PWM pairs.
				uint32_t NDEP45:1;	//This write-protectable bit determines if the PWM Channel 4-5 will be independent PWMs or complementary PWM pairs.
				uint32_t RSVD0:1;
				uint32_t BOTNEG01:1;	//This write-protectable bit determines the polarity for the bottom-side PWMs. 
				uint32_t BOTNEG23:1;	//This write-protectable bit determines the polarity for the bottom-side PWMs. 
				uint32_t BOTNEG45:1;	//This write-protectable bit determines the polarity for the bottom-side PWMs. 
				uint32_t RSVD1:1;
				uint32_t TOPNEG01:1;	//This write-protectable bit determines the polarity for the top-side PWMs. 
				uint32_t TOPNEG23:1;	//This write-protectable bit determines the polarity for the top-side PWMs. 
				uint32_t TOPNEG45:1;	//This write-protectable bit determines the polarity for the top-side PWMs. 
				uint32_t RSVD2:1;
				uint32_t EDG:1;	//his write-protectable bit determines whether all PWM channels will use Edge-Aligned or Center-Aligned wave forms.
				uint32_t RSVD3:17;
};
union PWM_CNFG_REG {
				uint32_t				all;
				struct  PWM_CNFG_BITS		bit;
};
struct PWM_CCTRL_BITS	{
				uint32_t SWP01:1;	//This bit is write-protected when ENHA is zero.
				uint32_t SWP23:1;	//This bit is write-protected when ENHA is zero.
				uint32_t SWP45:1;	//This bit is write-protected when ENHA is zero.
				uint32_t RSVD0:1;
				uint32_t VLMODE:2;	//These two bits determine the way the Value registers are being loaded. These bits are write-protected when ENHA is zero.
				uint32_t MSK0:1;	//The mask of the PWM logical channel 0.
				uint32_t MSK1:1;	//The mask of the PWM logical channel 1.
				uint32_t MSK2:1;	//The mask of the PWM logical channel 2.
				uint32_t MSK3:1;	//The mask of the PWM logical channel 3.
				uint32_t MSK4:1;	//The mask of the PWM logical channel 4.
				uint32_t MSK5:1;	//The mask of the PWM logical channel 5.
				uint32_t RSVD1:3;
				uint32_t ENHA	:1;	//Enable Hardware Acceleration 
				uint32_t RSVD2:15;
};
union PWM_CCTRL_REG {
				uint32_t				all;
				struct  PWM_CCTRL_BITS		bit;
};
struct PWM_PORT_BITS	{
				uint32_t FAULTPORT:1;	//This bit contains values of the fault inputs. This register is read only.
				uint32_t RSVD0:6;
				uint32_t FAULTVAL0:1;	//This bit contains the value of PWM0 output when fault happens and FPSEL=1
				uint32_t FAULTVAL1:1;	//This bit contains the value of PWM1 output when fault happens and FPSEL=1
				uint32_t FAULTVAL2:1;	//This bit contains the value of PWM2 output when fault happens and FPSEL=1
				uint32_t FAULTVAL3:1;	//This bit contains the value of PWM3 output when fault happens and FPSEL=1
				uint32_t FAULTVAL4:1;	//This bit contains the value of PWM4 output when fault happens and FPSEL=1
				uint32_t FAULTVAL5:1;	//This bit contains the value of PWM5 output when fault happens and FPSEL=1
				uint32_t RSVD1:2;
				uint32_t FPSEL0:1;	//When fault happens, this bit selects whether FAULTVAL0 controlling PWM output or setting PWM0 pin to input mode
				uint32_t FPSEL1	:1;	//When fault happens, this bit selects whether FAULTVAL1 controlling PWM1 output or setting PWM1 pin to input mode
				uint32_t FPSEL2:1;	//When fault happens, this bit selects whether FAULTVAL2 controlling PWM2 output or setting PWM2 pin to input mode
				uint32_t FPSEL3	:1;	//When fault happen, this bit selects whether FAULTVAL3 controlling PWM3 output or setting PWM3 pin to input mode
				uint32_t FPSEL4:1;	//When fault happens, this bit selects whether FAULTVAL4 controlling PWM4 output or setting PWM4 pin to input mode
				uint32_t FPSEL5:1;	//When fault happens, this bit selects whether FAULTVAL5 controlling PWM output or setting PWM5 pin to input mode
				uint32_t RSVD2:10;
};
union PWM_PORT_REG {
				uint32_t				all;
				struct  PWM_PORT_BITS		bit;
};
struct PWM_ICCTRL_BITS	{
				uint32_t ICC0:1;	//This bit controls PWM0/PWM1 pair.
				uint32_t ICC1:1;	//This bit controls PWM_2/PWM_3 pair.
				uint32_t ICC2:1;	//This bit controls PWM_4/PWM_5 pair.
				uint32_t RSVD0:1;
				uint32_t PAD_EN:1;	//The PWM_m output pads can be enabled or disabled by setting the PAD_EN bit. The power-up default has the pads disabled. This bit does not affect the functionality of the PWM, so the PWM can be energized with the output pads disabled. This enable is to power-up with a safe default value for the PWM drivers.
				uint32_t RSVD1:27;
};
union PWM_ICCTRL_REG {
				uint32_t				all;
				struct  PWM_ICCTRL_BITS		bit;
};
struct PWM_PSCR_BITS	{
				uint32_t CINV0:1;	//This bit controls the polarity of PWM compare output 0. 
				uint32_t CINV1:1;	//This bit controls the polarity of PWM compare output 1.
				uint32_t CINV2:1;	//This bit controls the polarity of PWM compare output 2. 
				uint32_t CINV3:1;	//This bit controls the polarity of PWM compare output 3. 
				uint32_t CINV4:1;	//This bit controls the polarity of PWM compare output 4. 
				uint32_t CINV5:1;	//This bit controls the polarity of PWM compare output 5. 
				uint32_t RSVD0:26;
};
union PWM_PSCR_REG {
				uint32_t				all;
				struct  PWM_PSCR_BITS		bit;
};
struct PWM_CNTRINI_BITS	{
				uint32_t INITVAL:16;	//PWM Counter Initial Vale (CNTRINI) Register
				uint32_t RSVD:16;
};
union PWM_CNTRINI_REG {
				uint32_t				all;
				struct  PWM_CNTRINI_BITS		bit;
};
/* ================================================================================ */
/* ================                       PWM                      ================ */
/* ================================================================================ */


/**
  * @brief Pulse-Width Modulation (PWM)
  */

typedef struct {                                    /*!< PWM Structure                                                         */
  __IO union PWM_CTRL_REG  CTRL;                              /*!< Control Register                                                      */
  __IO union PWM_FCTRL_REG  FCTRL;                             /*!< Fault Control Register                                                */
  __IO union PWM_FLTACK_REG  FLTACK;                            /*!< Fault Status/Acknowledge Register                                     */
  __IO union PWM_OUTCTRL_REG  OUTCTRL;                           /*!< Output Control Register                                               */
  __I  union PWM_CNTR_REG  CNTR;                              /*!< Counter Register                                                      */
  __IO union PWM_CMOD_REG  CMOD;                              /*!< Counter Modulo Register                                               */
  __IO union PWM_VAL_REG  VAL0;                              /*!< Value Register 0                                                      */
  __IO union PWM_VAL_REG  VAL1;                              /*!< Value Register 1                                                      */
  __IO union PWM_VAL_REG  VAL2;                              /*!< Value Register 2                                                      */
  __IO union PWM_VAL_REG  VAL3;                              /*!< Value Register 3                                                      */
  __IO union PWM_VAL_REG  VAL4;                              /*!< Value Register 4                                                      */
  __IO union PWM_VAL_REG  VAL5;                              /*!< Value Register 5                                                      */
  __I  uint32_t  RESERVED0[2];
  __IO union PWM_DTIM_REG  DTIM0;                             /*!< Deadtime Register 0                                                   */
  __IO union PWM_DTIM_REG  DTIM1;                             /*!< Deadtime Register 1                                                   */
  __IO union PWM_DMAP0_REG  DMAP0;                             /*!< Disable Mapping Register0                                             */
  __IO union PWM_DMAP1_REG  DMAP1;                             /*!< Disable Mapping Register1                                             */
  __IO union PWM_CNFG_REG  CNFG;                              /*!< Configure Register                                                    */
  __IO union PWM_CCTRL_REG  CCTRL;                             /*!< Channel Control Register                                              */
  __IO union PWM_PORT_REG  PORT;                              /*!< Port Register                                                         */
  __IO union PWM_ICCTRL_REG  ICCTRL;                            /*!< Internal Correction Control Register                                  */
 __I  uint32_t  RESERVED1[2];
  __IO union PWM_PSCR_REG  PSCR;                              /*!< Polarity Invert control Register                                      */
  __O  union PWM_CNTRINI_REG  CNTRINI;                           /*!< Counter Init Register                                                 */
} HHD32F0_PWM_TypeDef;

#define PWM	((HHD32F0_PWM_TypeDef	 *) HHD_PWM_BASE)

// PWM out pair
#define		PWM_COMPLEMENT		0
#define		PWM_DEPENDENT			1

// Align type
#define		PWM_CENTER				0
#define		PWM_EDGE					1

// PWM polarity
#define		PWM_POSITIVE			0
#define		PWM_NEGATIVE			1

// PWM PIN assignment
#define PWM0		0x01
#define PWM1 		0x02
#define PWM2 		0x04
#define PWM3		0x08
#define PWM4 		0x10
#define PWM5 		0x20

// interrupt type
#define		PWM_FULLINT				0
#define		PWM_HALFINT				1

// PWM fault type
#define		PWMFAULT			0
#define		ADCFAULT			1
#define		SWFAULT				2

//PWM fault clear type
#define		PWM_MANUAL				0
#define		PWM_AUTOMATIC			1

//Interrupt Enable or Disble
#define		DISINT				0
#define		ENINT					1


void PWM_Init(uint16_t freq,uint8_t pair, uint8_t align, uint8_t polarity);
void PWM_DeInit(void);
void PWM_SetRelaodFreq(uint8_t everytimes);
void PWM_SetDuty(uint8_t channelindex, uint16_t dutyval);
void PWM_SetRiseDeadZone(uint16_t rdtimeticks);
void PWM_SetFallDeadZone(uint16_t rdtimeticks);
void PWM_EnableFaultProtect(uint8_t faults, uint8_t cleartype, uint8_t faultint);
void PWM_ClearFault(void);
void PWM_Start(void);
void PWM_Stop(void);
void PWM_EnableInt(uint8_t inttype);

#endif /* end __PWM_H */
/*****************************************************************************
**                            End Of File
******************************************************************************/
