#ifndef MOTOR_H
#define MOTOR_H

#include "Pwm.h"

enum ErrorStatus{
	Clear = 0x00, 
	OverVbus = 0x01, 
	UnderVbus = 0x02, 
	OverTemperture = 0x04, 
	FaultLock = 0x08, 
	AOCP = 0x10, 
	POCP = 0x20, 
	LackPhase = 0x40, 
	LackPhaseRun = 0x80 
};

enum MotorStatus
{
	M_OFF = 0, 
	M_INIT = 1, 
	M_TAILWIND = 2, 
	M_IPD = 3,
	M_START = 4,
	M_RUN = 5, 
	M_STOP = 6, 
	M_BREAK = 7, 
	M_ERROR = 8, 
	M_BMF_BREAK = 9,
	M_LACK_PHASE = 10
};

#define Current_Control 0
#define Speed_Control 1
#define Power_Limit 2
#define Power_Control 3

#define Timer0_1ms 1
#define Timer1_10ms 10

//<<< Use Configuration Wizard in Context Menu >>>
//<h> Set motor parameters
	//<o> Motor_Pole <0-30:2>
		#define POLE 2*10 
		#define POLE_PAIRS POLE/2

	//<o> Motor SMO_G <0-32767>
	//<i> Formula : G = Ts / Ls/2
		#define G 17000

	//<o> Motor SMO_F <0-32767>
	//<i> Formula : F = 1 - (G * Rs/2))
		#define F 32346

	//<o> Motor SMO_Kslf <0-32767>
	//<i> Description : Low Pass Filter Gain : Kslf
		#define Kslf 10000

	//<o> Motor SMO_Z-Corr <0-32767> 
		#define ZCorr 32767

	//<o> Motor SMO Kslide (Sat) <0-32767>
		#define Kslide 16383

	//<o> Motor SMO MaxSmcError (Limit) <0-32767>
		#define MaxSmcError 32767

//MDRFD0
	//Motor SMO Gain (Linear : Q15(Kslide/MaxSmcError))
		#define SmoGain 32767
//</h>

//<h> Set Rshunt and OPA_Gian
	//<o> Rshunt (unit : 0.1m Ohm)
		#define R_SHUNT (float)1000/10000 

	//<o.4..5> OPA_Gian <0=> 1 Gain <1=> 2.5 Gain <2=> 5 Gain <3=> 10 Gain
		#define OPA_GAIN_REGS 0x20
		
		#if (OPA_GAIN_REGS == 0x00)
			#define OPA_GAIN (float)10/10
		#endif
		#if (OPA_GAIN_REGS == 0x10)
			#define OPA_GAIN (float)25/10 
		#endif
		#if (OPA_GAIN_REGS == 0x20)
			#define OPA_GAIN (float)50/10 
		#endif
		#if (OPA_GAIN_REGS == 0x30)
			#define OPA_GAIN (float)100/10 
		#endif
		
	#define I_AMPLIFIER (unsigned short)((float)(((R_SHUNT * OPA_GAIN * 1023))/5)*64) 
//</h>

//<h> Set the motor tuning process
//<o> FOC_Control_Stage <1=> OpenLoop <2=> CloseLoop 
//<i> OpenLoop  : OpenLoop (Note : Fine tune G,F,Kslide,Kslf parameters. After operation, you need to manually switch CloseLoopFlag)
//<i> CloseLoop : CloseLoop(Note : Automatically switch CloseLoopFlag after operation)
	#define SOP_LEVEL 2

	//<o> Set IQ parking duration(unit : ms) <1-32767>
		#define I_ALIG_DURATION 10 // unit : mSec ex. 100 * 50us = 5ms
 
	#if ((SOP_LEVEL == 1) || (SOP_LEVEL == 2))
		//<o> Set SMO_PLL initial speed (unit : 10rpm)
			#define FREQ_FIRST_START_VALUE (short) ((float) 1 * 32767 / BASE_RPM) 

		//<o> Set SMO_PLL end speed (unit : 10rpm)
			#define FREQ_FINAL_START_VALUE (short) ((float) 400 * 32767 / BASE_RPM)

		//<o> Set PLL accumulation <1-100>
			#define PLL_ACC 2

		//<o> Set SMO_RAMP acceleration slope (unit : ms) <1-32767>
			#define SMO_RAMP 1 
	#endif

	//<o> Set SMO_DELAY Delay time (unit : ms) <0-65535>
		#define SMO_DELAY_DURATION 		10
//</h>

//<h> Set FOC LOOP Parameter
	//<h> IQ
		//<h> Set IQ Current parameter
			//<o> Set IQ Initial current (unit : mA)
				#define IQ_INIT_START_VALUE (signed short)((float) 0/1000 * I_AMPLIFIER) 

			//<o> Set IQ Starting current (unit : mA)
				#define IQ_FIRST_START_VALUE (signed short)((float) 0/1000  * I_AMPLIFIER)

			//<o> Set IQ End current (unit : mA)
				#define IQ_FINAL_START_VALUE (signed short)((float) 500/1000 * I_AMPLIFIER)

			//<o> IQ_TailWind Value (unit : mA)
				#define IQ_FINAL_TAILWIND_START_VALUE (signed short)((float) 500/1000  * I_AMPLIFIER) 
		//</h>
	
	//<h> Set IQ PI parameters
		//<o> Kp parameters <0-32767>
			#define Iq_Kp 28700
		
		//<o> Ki parameters <0-32767>
			#define Iq_Ki 200
		
		//<o> Kt parameters <0-32767>
			#define Iq_Kt 32767
		
		//<o> MaxLimit parameters <0-32767>
			#define Iq_MaxLimit 32767
		
		//<o> MinLimit parameters <0-32767>
			#define Iq_MinLimit -32767
	//</h>
//</h>
#define I_ALIG_STEP_VALUE ((float)(IQ_FIRST_START_VALUE - IQ_INIT_START_VALUE) / I_ALIG_DURATION)

	//<h> ID
		//<h> Set ID Current parameter
			//<o> Set ID Starting current (unit : mA)
				#define ID_FIRST_START_VALUE (signed short)((float) -0/1000  * I_AMPLIFIER)

			//<o> Set ID End current (unit : mA)
				#define ID_FINAL_START_VALUE (signed short)((float) -0/1000  * I_AMPLIFIER)

			// Set ID_TailWind Value (unit : mA)
			//#define ID_FINAL_TAILWIND_START_VALUE (signed short)((float) -0/1000 * I_AMPLIFIER) 
		//</h>
		
		//<h> Set ID PI parameters
			//<o> Kp parameters <0-32767>
				#define Id_Kp 28700
		
			//<o> Ki parameters <0-32767>
				#define Id_Ki 200
		
			//<o> Kt parameters <0-32767>
				#define Id_Kt 	32767
		
			//<o> MaxLimit parameters <0-32767>
				#define Id_MaxLimit 	32767
		
			//<o> MinLimit parameters <0-32767>
				#define Id_MinLimit 	-32767
		//</h>
	//</h>

	//<h> SPEED
		//<h> Set SPEED PI parameters
			//<o> Start Kp <0-32767>
				#define Spd_Kp_Start 	0
				
			//<o> Final Kp <0-32767>
				#define Spd_Kp_Final 	6000
				
			//<o> Ki parameters <0-32767>
				#define Spd_Ki 130
				
			//<o> Kt parameters <0-32767>
				#define Spd_Kt 32767
				
			//<o> MaxLimit (unit : mA) <0-32767>
				#define Spd_MaxLimit (signed short)((float) 1400/1000 * I_AMPLIFIER)  // 450 1.30
	
			//<o> MinLimit  (unit : mA) <0-32767>
				#define Spd_MinLimit (signed short)((float) -0/1000 * I_AMPLIFIER)
	
			//<o> Speed Cycle parameters <0-255>
				#define Spd_Cyc 20
		//</h>
	//</h>

	//<h> PLL
		//<o> Start Kp <0-32767>
			#define Pll_Kp_Start 	1000
			
		//<o> Final Kp <0-32767>
			#define Pll_Kp_Final 	1000
			
		//<o> Ki parameters <0-32767>
			#define Pll_Ki 		20
		
		//<h> HeadWind/TailWind
			// <o> Kp parameters <0-32767>
				#define Pll_Kp_TailWind 	1000
				
			// <o> Ki parameters <0-32767>
				#define Pll_Kp_HeadWind 	0
		//</h>
		
		//<o> Kt parameters <0-32767>
			#define Pll_Kt 		32767
			
		//<o> MaxLimit parameters <0-32767>
			#define Pll_MaxLimit 12000
			
		//<o> MinLimit parameters <0-32767>
			#define Pll_MinLimit -32767
	//</h>
//</h>

//<h> Set motor control program
	//<h> Set Peripheral Control
		//<e> VSP control commands Enable/Disable
			#define VSP_TRI 0
			//<o> Set VSP_CH <0=> CH0 <1=> CH1 <2=> CH2 <3=> CH3 <4=> CH4 <5=> CH5 <6=> CH6 <7=> CH7 
				#define VSP_CH 	7

			//<e> VSP_CH_Inver Enable/Disable 
				#define Inver 	0
			//</e>

			//<e> Vsp_LookUpTable Enable/Disable 
				#define Vsp_LookUpTable 	0
			//</e>
		//</e>
	//</h>
	
	//<h> Set the main control loop
		//<o> Control_Mode <0=> Phase Current_Control <1=> Speed_Control <2=> Power_Limit <3=> Power_Control
			#define CONTROL_MODE 1

		//<h> Current_Control
			//<o> Set the rated output phase current(max) (unit : mA) <0-30000>
				#define IQ_MAX_LIMIT_VALUE (signed short)((float) 540/1000 * I_AMPLIFIER) 
		//</h>

		//<h> Speed_Control
			//<o> Set the rated output speed (max) (unit : 10rpm)
				#define SPEED_MAX_LIMIT_VALUE (short) ((float) 10500 * 32767 / BASE_RPM) 
		//</h>

		//<h> Power_Control & Power_Limit
			//<o> Set the rated output power (max) (unit : 0.01W) <0-10000>
				#define WATT_LIMIT_VALUE (unsigned long) 1800
			
			//<o> Set power magnification parameters (unit : 10^-5)
				#define dPOWER_GAIN ((float) 100/100000) 
				
			//<o> Set I_BUS A/D Channel <0=> CH0 <1=> CH1 <2=> CH2 <3=> CH3 <4=> CH4 <5=> CH5 <6=> CH6 <7=> CH7
				#define I_BUS_CH 2
			
			//<o> POWER_SOP <1=> LEVEL 1 <2=> LEVEL 2
			//<i> LEVEL_1 : Not run
			//<i> LEVEL_2 : Procedure run
				#define POWER_SOP 	2

			//<e> Power_LookUpTable Enable/Disable 
				#define Power_LookUpTable 	0
			//</e>
		//</h>
	//</h>

	//<h> Set other functions
		//<o> Set CW/CCW steering <0=> CW <1=>CCW
			#define CW_CCW 1

		//<o> Set Stop_Fun stop speed (unit : 10rpm)
			#define STOP_SPEED_VALUE (short) ((float) 400 * 32767 / BASE_RPM) // unit : 10Rpm
  
		//<e> IPD Enable/Disable
		//</e>
			#define IPD_FUNCTION 0
			#if (IPD_FUNCTION == 1)
			#endif
			
		//<e> Brake control Enable/Disable
			#define BREAK_FUNCTION 0
			#if (BREAK_FUNCTION == 1)
				//<o> Set braking force (unit : %) <0-100>
					#define BREAK_DUTY (float)10/100
					#define BREAK_DUTY_VALUE (unsigned short)((float) MPWMDATA_REGS * BREAK_DUTY)
			#else
				#define BREAK_DUTY (float)99/100
				#define BREAK_DUTY_VALUE (unsigned short)((float) MPWMDATA_REGS * BREAK_DUTY)
			#endif
		//</e>
	//</h>

	//<o> Slow Speed Detection <1=> Enable <0=> Disable
				#define SLOW_SPEED 0

			//<o> TAILWIND_BREAK <1=> Enable <0=> Disable
				#define TAILWIND_BREAK 0

			//<o> HEADWIND_BREAK <1=> Enable <0=> Disable
				#define HEADWIND_BREAK 0

			//<o> Break Phase Current Value (unit : mA)
				#define BREAK_PHASE_CURRENT_VALUE (signed short)((float) 300/1000 * I_AMPLIFIER)

			//<o> Bemf Break Time (unit : ms)
				#define BREAK_DURATION 150
//</h>

//<h> Set Fairwind and Headwind judgment function
	//<e> BEMF Fairwind/Headwind judgment (resistance) Enable/Disable
		#define BEMF_TWO_TAILWIND_FUNCTION_RES 0
		#if(BEMF_TWO_TAILWIND_FUNCTION_RES == 1)
			//<o> BEMF_TAILWIND_IQ_OUT_VALUE (unit : Val)
				#define BEMF_TAILWIND_IQ_OUT_VALUE (short)(8000)

			// BEMF_TAILWIND_SPEED_VALUE (unit : 10rpm)
				#define BEMF_TAILWIND_SPEED_VALUE FREQ_FINAL_START_VALUE //(short) ((float) 180 * 32767 / BASE_RPM) // unit : Rpm

			//<o> BEMF_V_CH <0=> CH0 <1=> CH1 <2=> CH2 <3=> CH3 <4=> CH4 <5=> CH5 <6=> CH6 <7=> CH7 
				#define BEMF_V_CH 4

			//<o> BEMF_W_CH <0=> CH0 <1=> CH1 <2=> CH2 <3=> CH3 <4=> CH4 <5=> CH5 <6=> CH6 <7=> CH7 
				#define BEMF_W_CH 5

			//<o> BEMF_TAILWIND_SOP<1=> LEVEL 1 <2=> LEVEL 2
			//<i> LEVEL_1 : No IPDStart_Fun, and it will stop at TailWindDetect_Fun, TailWindDetect_Bemf_Fun, TailWindDetect_OneBemf_Fun, TailWindDetect_TwoBemf_Fun 
			//<i> LEVEL_2 : Procedure run
				#define BEMF_TAILWIND_SOP 1

			//<o1> BEMF_TAILWIND_SPEED_MAX (unit : 10rpm) <10-1500>
				#define BEMF_TAILWIND_SPEED_MAX (unsigned short)((float) PWM_Frequency*120/POLE/1200) // For MDRFxx

			//<o1> BEMF_TAILWIND_SPEED_MIN (unit : 10rpm) <10-1500>
				#define BEMF_TAILWIND_SPEED_MIN (unsigned short)((float) PWM_Frequency*120/POLE/300) // For MDRFxx

			//<o1> BEMF_HEADWIND_SPEED_MAX (unit : 10rpm) <10-1500>
				#define BEMF_HEADWIND_SPEED_MAX (unsigned short)((float) PWM_Frequency*120/POLE/1200) // For MDRFxx
				//#define BEMF_TAILWIND_SPEED_MAX (unsigned short)((float)93750 / ((600 * POLE_PAIRS)/60)) // For MDSFxx

			//<o1> BEMF_HEADWIND_SPEED_MIN (unit : 10rpm) <10-1500>
				#define BEMF_HEADWIND_SPEED_MIN (unsigned short)((float) PWM_Frequency*120/POLE/300) // For MDRFxx
				//#define BEMF_TAILWIND_SPEED_MIN (unsigned short)((float)93750 / ((60 * POLE_PAIRS)/60)) // For MDSFxx
		#endif
	//</e>
	
	//<e> BEMF Fairwind/Headwind judgment (Diode) Enable/Disable
	// <i> Note: Requires Enable brake control function
		#define BEMF_TWO_TAILWIND_FUNCTION_DIODE 0
		#if (BEMF_TWO_TAILWIND_FUNCTION_DIODE == 1)
			//<o> BEMF_TAILWIND_IQ_OUT_VALUE (unit : Val) <0-60000>
				#define BEMF_TAILWIND_IQ_OUT_VALUE (short)(8000)

			// BEMF_TAILWIND_SPEED_VALUE (unit : 10rpm) 
				#define BEMF_TAILWIND_SPEED_VALUE FREQ_FINAL_START_VALUE //(short) ((float) 180 * 32767 / BASE_RPM) // unit : Rpm

			//<o> BEMF_V_CH <0=> CH0 <1=> CH1 <2=> CH2 <3=> CH3 <4=> CH4 <5=> CH5 <6=> CH6 <7=> CH7 
				#define BEMF_V_CH 4

			//<o> BEMF_W_CH <0=> CH0 <1=> CH1 <2=> CH2 <3=> CH3 <4=> CH4 <5=> CH5 <6=> CH6 <7=> CH7 
				#define BEMF_W_CH 5

			//<o> BEMF_TAILWIND_SOP <1=> LEVEL 1 <2=> LEVEL 2
			//<i> LEVEL_1 : No IPDStart_Fun, and it will stop at TailWindDetect_Fun, TailWindDetect_Bemf_Fun, TailWindDetect_OneBemf_Fun, TailWindDetect_TwoBemf_Fun 
			//<i> LEVEL_2 : Procedure run
				#define BEMF_TAILWIND_SOP 2

			//<o1> BEMF_TAILWIND_SPEED_MAX (unit : 10rpm) <10-1500>
				#define BEMF_TAILWIND_SPEED_MAX (unsigned short)((float) PWM_Frequency*120/POLE/1200) // For MDRFxx

			//<o1> BEMF_TAILWIND_SPEED_MIN (unit : 10rpm) <10-1500>
				#define BEMF_TAILWIND_SPEED_MIN (unsigned short)((float) PWM_Frequency*120/POLE/300) // For MDRFxx

			//<o1> BEMF_HEADWIND_SPEED_MAX (unit : 10rpm) <10-1500>
				#define BEMF_HEADWIND_SPEED_MAX (unsigned short)((float) PWM_Frequency*120/POLE/600) // For MDRFxx
				//#define BEMF_TAILWIND_SPEED_MAX (unsigned short)((float)93750 / ((600 * POLE_PAIRS)/60)) // For MDSFxx

			//<o1> BEMF_HEADWIND_SPEED_MIN (unit : 10rpm) <10-1500>
				#define BEMF_HEADWIND_SPEED_MIN (unsigned short)((float) PWM_Frequency*120/POLE/300) // For MDRFxx
				//#define BEMF_TAILWIND_SPEED_MIN (unsigned short)((float)93750 / ((60 * POLE_PAIRS)/60)) // For MDSFxx
		#endif
	//</e>

	//<e> BEMF TailWind Fun (One BEMF) Enable/Disable
		#define BEMF_ONE_TAILWIND_FUNCTION 0
		#if (BEMF_ONE_TAILWIND_FUNCTION == 1)
			//<o> BEMF_TAILWIND_IQ_OUT_VALUE (unit : Val) <0-32700>
				#define BEMF_TAILWIND_IQ_OUT_VALUE (short)(8000)

			//<o> BEMF_CH <0=> CH0 <1=> CH1 <2=> CH2 <3=> CH3 <4=> CH4 <5=> CH5 <6=> CH6 <7=> CH7 
				#define BEMF_CH 4

			//<o> BEMF_CH_LATEST_THETA <64=> 60Deg <128=> 120Deg <192=> 180Deg <256=> 240Deg <320=> 300Deg <382=> 360Deg
			//<i> 60Deg Leo , 180Deg TT
				#define BEMF_CH_LATEST_THETA 128

			//<o> BEMF_TAILWIND_SOP <1=> LEVEL 1 <2=> LEVEL 2
			//<i> LEVEL_1 : No IPDStart_Fun, and it will stop at TailWindDetect_Fun, TailWindDetect_Bemf_Fun, TailWindDetect_OneBemf_Fun, TailWindDetect_TwoBemf_Fun 
			//<i> LEVEL_2 : Procedure run
				#define BEMF_TAILWIND_SOP 2

			//<o1> BEMF_TAILWIND_SPEED_MAX (unit : 10rpm) <0-1500>
				#define BEMF_TAILWIND_SPEED_MAX (unsigned short)((float) PWM_Frequency*120/POLE/600) // For MDRFxx
				//#define BEMF_TAILWIND_SPEED_MAX (unsigned short)((float)93750 / ((1500 * POLE_PAIRS)/60))

			//<o1> BEMF_TAILWIND_SPEED_MIN (unit : 10rpm) <0-1500>
				#define BEMF_TAILWIND_SPEED_MIN (unsigned short)((float) PWM_Frequency*120/POLE/180) // For MDRFxx
				//#define BEMF_TAILWIND_SPEED_MIN (unsigned short)((float)93750 / ((60 * POLE_PAIRS)/60))
		#endif
	//</e>
	
	#if ((BEMF_TWO_TAILWIND_FUNCTION_RES == 0) && (BEMF_TWO_TAILWIND_FUNCTION_DIODE == 0)  && (BEMF_ONE_TAILWIND_FUNCTION == 0))
	#define BEMF_TAILWIND_SPEED_VALUE 0
	#endif
//</h>
	
// <h> Set motor protection function
	//<e> Overvoltage/Undervoltage protection (OVP/UVP)
	//<i> Note: Need to use Vbus voltage divider resistors
	//<i> (OVER) (CLEAR_OVER)                         (CLEAR_UNDER) (UNDER)
	//<i> ----|-----------|------------------------------|-------------|---->
#define Vbus_Protect 1
#if (Vbus_Protect == 1)
#endif

//<o> Set Vbus A/D Channel <0=> CH0 <1=> CH1 <2=> CH2 <3=> CH3 <4=> CH4 <5=> CH5 <6=> CH6 <7=> CH7 
	#define V_BUS_CH 2

//<o> Set Vbus rate parameter <0-65535>
//<i> VBUS_GAIN = (Vbus_avg / Input voltage)*1000
	#define VBUS_GAIN ((float) 2160 / 1000)
		
//<o> OVP Values (unit : 0.1V) <0-4000>
	#define OVER_BUS_VOLT_VALUE (unsigned short)((float) 3800 * 0.1 * VBUS_GAIN) // unit : V * Gain

//<o> OVP recovery Values (unit : 0.1V) <0-4000>
	#define CLEAR_OVER_BUS_VOLT_VALUE (unsigned short)((float) 3750 * 0.1 * VBUS_GAIN) // unit : V * Gain

//<o> UVP recovery Values (unit : 0.1V) <0-4000>
	#define CLEAR_UNDER_BUS_VOLT_VALUE (unsigned short)((float) 1050 * 0.1 * VBUS_GAIN) // unit : V * Gain

//<o> UVP Values (unit : 0.1V) <0-4000>
	#define UNDER_BUS_VOLT_VALUE (unsigned short)((float) 800 * 0.1 * VBUS_GAIN) // unit : V * Gain

//<o> BUS_VOLT_DURATION (unit : ms) <10-30000>
//<i> Judgment every 10ms.
	#define BUS_VOLT_DURATION 	50 // unit : mSec
// </e>

//<e> Locked-rotor protection (LRP)
#define FaultLock_Protect 1
#if (FaultLock_Protect == 1)
#endif

//<o> Motor speed abnormally high value (unit : 10rpm)
	#define OverSpeed (short) ((float) 12000 * 32767 / BASE_RPM) 

//<o> Motor speed abnormally low value (unit : 10rpm)
	#define UnderSpeed (short) ((float) 600 * 32767 / BASE_RPM)
		
//<o> LRP DURATION (unit : ms) <10-30000>
//<i> Judgment every 10ms.	
	#define FAULTLOCK_DELAY_DURATION 200
// </e>
	
//<e> Over temperature protection(OTP)
//<i> Note: Need to use temperature sensor
//<i> (OVER) (CLEAR_OVER)                         (CLEAR_UNDER) (UNDER)
//<i> ----|-----------|------------------------------|-------------|---->
#define Temperture_Protect 0
#if (Temperture_Protect == 1)
#endif
//<o> Set OTP A/D Channel <0=> CH0 <1=> CH1 <2=> CH2 <3=> CH3 <4=> CH4 <5=> CH5 <6=> CH6 <7=> CH7 
	#define TEMPERTURE_CH 	5
	
//<o> OTP A/D Values (unit : Val) <0-1023>
	#define OVER_TEMPERTURE_VALUE 	670 // unit : DegC * Gain

//<o> OTP recovery A/D Values (unit : Val) <0-1023>
	#define CLEAR_OVER_TEMPERTURE_VALUE 620 // unit : DegC * Gain
	
// <o> OVER_TEMPERTURE_LOAD_REDUCE_VALUE (unit : Val) <0-1023>
#define OVER_TEMPERTURE_LOAD_REDUCE_VALUE 670 // unit : DegC * Gain
	

//<o> TEMPERTURE_DURATION (unit : ms) <10-30000>
//<i> Judgment every 10ms.
#define TEMPERTURE_DURATION 	500 // unit : mSec
// </e>

// <e> Heat_Temperture_Protect Enable/Disable
#define Heat_Temperture_Protect 1
#if (Heat_Temperture_Protect == 1)
#endif
// <o> Set Heat Temperture A/D Channel <0=> CH0 <1=> CH1 <2=> CH2 <3=> CH3 <4=> CH4 <5=> CH5 <6=> CH6 <7=> CH7 
#define HEAT_TEMPERTURE_CH 3

// <o> OVER_HEAT_TEMPERTURE A/D Values (unit : Val) <0-1023>
#define OVER_HEAT_TEMPERTURE_VALUE 150 // unit : DegC * Gain

// <o> HEAT_TEMPERTURE_OPEN_CIRCUIT A/D Values (unit : Val) <0-1023>
#define HEAT_TEMPERTURE_OPEN_CIRCUIT_VALUE 1000 // unit : DegC * Gain

// <o> HEAT_TEMPERTURE_DURATION (unit : ms) <10-30000>
#define HEAT_TEMPERTURE_DURATION 500 // unit : mSec

// </e>

	//<e> Phase current protection
	//<o2> Phase Ia,Ib,Ic Value (unit : mA)
	//<o4> POCP_Duration (unit : ms)
#define POCP_Protect 0
#if (POCP_Protect == 1)
#define PHASE_OCP (float)700/1000 
#define PHASE_OCP_VALUE (signed short)((float) PHASE_OCP * I_AMPLIFIER) // unit : A * Gain
#define PHASE_OCP_DURATION 50
#endif
// </e>

// PhaseLoss_Fun Enable/Disable
#define PhaseLoss_Fun 0
#if (PhaseLoss_Fun == 1)
#endif


// <e> MotorLackPhase_Fun Enable/Disable
// <i> note : Measure Ia,Ib,Ic
#define MotorLackPhase 0
#if (MotorLackPhase == 1)

// <o> MotorLackPhase_SOP <1=> LEVEL 1 <2=> LEVEL 2
// <i> LEVEL_1 : Procedure will stop at MotorLackPhase_Fun 
// <i> LEVEL_2 : Procedure run
#define MotorLackPhase_SOP 2

// <o> Set Vq Detection Value (unit : Val) <0-4000>
#define Detect_Vq (signed short)(2000)

// <o> Set abs(IaFb) Detection Value (unit : mA) <0-1000>
#define MotorLackPhase_Threshold_0 (signed short)((float) 25/1000  * I_AMPLIFIER) //6547.2

// <o> Set abs(IbFb) Detection Value (unit : mA) <0-1000>
#define MotorLackPhase_Threshold_1 (signed short)((float) 25/1000  * I_AMPLIFIER) //6547.2

// <o> LackPhase_Duration  (unit : ms) <10-30000>
#define LackPhase_Duration 500

#endif
// </e>

// <e> MotorLackPhase_Run_Fun Enable/Disable
// <i> note : measure Ia,Ib,Ic
#define MotorLackPhase_Run 0
#if (MotorLackPhase_Run == 1)
// <o> Set abs(IaFb) Detection Value (unit : mA) <0-1000>
#define MotorLackPhase_Run_Threshold_0 (signed short)((float) 50/1000  * I_AMPLIFIER) //6547.2

// <o> Set abs(IbFb) Detection Value(unit : mA) <0-1000>
#define MotorLackPhase_Run_Threshold_1 (signed short)((float) 50/1000  * I_AMPLIFIER) //6547.2

// <o> Set abs(IaFb-IbFb) Detection Value (unit : mA) <0-1000>
#define MotorLackPhase_Run_Threshold_2 (signed short)((float) 100/1000  * I_AMPLIFIER) //6547.2

// <o> LackPhase_Run_Duration  (unit : ms) <10-30000>
#define LackPhase_Run_Duration 100
#endif
// </e>
// </h>

// <o> TailWind Determine Time(unit : ms)
// <i> unit : mSec ex. 2000 * 50us = 100ms
#define TAILWIND_DURATION 200 // unit : mSec ex. 2000 * 50us = 100ms

// <o> Stop_Fun Time (unit : ms)
#define STOP_SPEED_DURATION 200

// <h> Set Protection to retry

// <e> AOCP_Retry_Enable
#define AOCP_Retry_ENABLE 1
// </e>

// <e> POCP_Retry_Enable
#define POCP_Retry_ENABLE 0
// </e>

// <e> FaultLock_Retry_Enable
#define FaultLock_Retry_ENABLE 1
// </e>

// <e> MotorLackPhase_Retry_Enable
#define MotorLackPhase_Retry_ENABLE 1
// </e>

// <e> MotorLackPhase_Run_Retry_Enable
#define MotorLackPhase_Run_Retry_ENABLE 1
// </e>

// <o> Set the number of retries <0-255>
#define RETRY_COUNT 10
// <o> Set retry delay time (unit : ms) <0-32767>
#define RESTART_DURATION 5000
// </h>

// <h> Error code(MotorErrorState)
	// <i> Clear = 0x00 (Normal)
	// <i> OverVbus = 0x01 (Over voltage)
	// <i> UnderVbus = 0x02 (under voltage)
	// <i> OverTemperature = 0x04 (Over temperature)
	// <i> FaultLock = 0x08 (stall)
	// <i> AOCP = 0x10 (Over current)
	// <i> POCP = 0x20 (abnormal phase current)
	// <i> LackPhase = 0x40 (static lack phase)
	// <i> LackPhaseRun = 0x80 (dynamic lack phase)
// </h>
// <<< end of configuration section >>>

// MOTOR_CONT1
#define MPWMSEL 0x40
#define MPWMEN 0x20
#define IQINSEL 0x10
#define FOCANGSEL 0x08

// MOTOR_CONT2
#define MPWMCPSEN 0x80
#define MPWMCPSTP 0x00
//#define MPWMCPSTP 0x20
//#define MPWMCPSTP 0x60
#define SVPWMPS 0x08 // CW or CCW
#define CPS_LIMIT_EN 0x00
//#define SVPWMMODE 0x00 // SVPwm
#define SVPWMMODE 0x10 // DPwm

// MOTOR_CONT3
#define SMO_CMP_VALUE 0x40

// PI_GAIN
#define PLLKIGEN 0x01
#define PLLKPGEN 0x02
#define SPEEDKIGEN 0x04
#define SPEEDKPGEN 0x08
#define IDKIGEN 0x10
#define IDKPGEN 0x20
#define IQKIGEN 0x40
#define IQKPGEN 0x80

// PI_TMSR
#define PLLTMEN 0x01
#define PLLTMSEL 0x02
#define SPEEDTMEN 0x04
#define SPEEDTMSEL 0x08
#define IDTMEN 0x10
#define IDTMSEL 0x20
#define IQTMEN 0x40
#define IQTMSEL 0x80

//FOCCONT
#define SPEEDEN 0x01
#define PLLEN 0x02
#define ADCTRIG 0x04
#define INVADCD 0x08
#define ESTCR 0x00
#define PICLEAR 0x80

#define IQ_CMD_MACRO(v) SFR_PAGE = 0; PI_CMD = v
#define ID_CMD_MACRO(v) SFR_PAGE = 1; PI_CMD = v
#define SPEED_CMD_MACRO(v) SFR_PAGE = 2; PI_CMD = v
#define PLL_CMD_MACRO(v) SFR_PAGE = 3; PI_CMD = v

#define IQ_KP_MACRO(v) SFR_PAGE = 0; PI_KP = v
#define ID_KP_MACRO(v) SFR_PAGE = 1; PI_KP = v
#define SPEED_KP_MACRO(v) SFR_PAGE = 2; PI_KP = v
#define PLL_KP_MACRO(v) SFR_PAGE = 3; PI_KP = v

#define IQ_KI_MACRO(v) SFR_PAGE = 0; PI_KI = v
#define ID_KI_MACRO(v) SFR_PAGE = 1; PI_KI = v
#define SPEED_KI_MACRO(v) SFR_PAGE = 2; PI_KI = v
#define PLL_KI_MACRO(v) SFR_PAGE = 3; PI_KI = v

#define SPEED_UI_MACRO(v) SFR_PAGE = 2; PI_UI = v
#define PLL_UI_MACRO(v) SFR_PAGE = 3; PI_UI = v

#define IQ_MAX_MACRO(v) SFR_PAGE = 0; PI_LMT = v
#define ID_MAX_MACRO(v) SFR_PAGE = 1; PI_LMT = v
#define SPEED_MAX_MACRO(v) SFR_PAGE = 2; PI_LMT = v
#define PLL_MAX_MACRO(v) SFR_PAGE = 3; PI_LMT = v

#define GS_MACRO(v) SFR_PAGE = 0; SMO_D1 = v
#define SMO_KSLIDE_MACRO(v) SFR_PAGE = 1; SMO_D1 = v
#define ANG_BASE_MACRO(v) SFR_PAGE = 2; SMO_D1 = v

#define SMO_ANG_MACRO(v) SFR_PAGE = 6; SMO_D1 = v

#define FS_MACRO(v) SFR_PAGE = 0; SMO_D2 = v
#define SMO_FILTER_MACRO(v) SFR_PAGE = 1; SMO_D2 = v
#define ANG_SHIFT_MACRO(v) SFR_PAGE = 2; SMO_D2 = v

#define SPEED_MACRO(v) SFR_PAGE = 6; SMO_D2 = v

#define VQ_OFFSET_MACRO(v) SFR_PAGE = 0; VDQ_OFST = v; SYNC = 0x55
#define VD_OFFSET_MACRO(v) SFR_PAGE = 1; VDQ_OFST = v; SYNC = 0x55

#define CPU_ANG_MACRO(v) CPU_ANG = v; SYNC = 0x55
#define FOC_ANG_MACRO(v) SFR_PAGE = 6; FOC_D1 = v
#define SVPWM_AMP_MACRO(v) SFR_PAGE = 6; FOC_D2 = v

#define GET_SPEED_MACRO(v) SFR_PAGE = 6; v = SMO_D2
#define GET_VQ_MACRO(v) SFR_PAGE = 0; v = FOC_D2
#define GET_IQ_MACRO(v) SFR_PAGE = 0; v = FOC_D1

#define DATA_FILTER(Data_I,Data_C,Data_O,Data_T,Data_F) (Data_C = Data_C + Data_I - Data_O, Data_O = (Data_T)(Data_C >> Data_F)) 

#define Uint32_Div_Uint16_MACRO(Dividend,Divisor,Answer)\
MD_MODE |= 0x02;\
MD0 = *(((unsigned char *)&Dividend)+3);\
MD1 = *(((unsigned char *)&Dividend)+2);\
MD2 = *(((unsigned char *)&Dividend)+1);\
MD3 = *(((unsigned char *)&Dividend)+0);\
MD4 = *(((unsigned char *)&Divisor )+1);\
MD5 = *(((unsigned char *)&Divisor )+0);\
while((MD_MODE & 0x10) == 0x10);\
*(((unsigned char *)&Answer)+3) = MD0;\
*(((unsigned char *)&Answer)+2) = MD1;\
*(((unsigned char *)&Answer)+1) = MD2;\
*(((unsigned char *)&Answer)+0) = MD3

#define Uint16_Div_Uint16_MACRO(Dividend,Divisor,Answer)\
MD_MODE |= 0x02;\
MD0 = *(((unsigned char *)&Dividend)+1);\
MD1 = *(((unsigned char *)&Dividend)+0);\
MD4 = *(((unsigned char *)&Divisor )+1);\
MD5 = *(((unsigned char *)&Divisor )+0);\
while((MD_MODE & 0x10) == 0x10);\
*(((unsigned char *)&Answer)+1) = MD0;\
*(((unsigned char *)&Answer)+0) = MD1

#define Uint16_Mult_Uint16_MACRO(MultCand,MultCator,Answer)\
MD_MODE |= 0x02;\
MD0 = *(((unsigned char *)&MultCand )+1);\
MD4 = *(((unsigned char *)&MultCator)+1);\
MD1 = *(((unsigned char *)&MultCand )+0);\
MD5 = *(((unsigned char *)&MultCator)+0);\
while((MD_MODE & 0x10) == 0x10);\
*(((unsigned char *)&Answer)+3) = MD0;\
*(((unsigned char *)&Answer)+2) = MD1;\
*(((unsigned char *)&Answer)+1) = MD2;\
*(((unsigned char *)&Answer)+0) = MD3

extern short SpeedCmd;
extern short CurrentCmd;
extern short SpeedCmdTemp;
extern short CurrentCmdTemp;
extern unsigned char MotorDir;

extern unsigned char SystemState;
extern unsigned char MotorState;
extern unsigned char MotorErrorState;
extern unsigned char MotorErrorStateOld;
extern unsigned char MotorFaultState;

extern unsigned short VbusTemp;
extern unsigned short IbusTemp;
extern unsigned short Vbus_avg;
extern unsigned short Ibus_avg;
//extern unsigned short VbusOffset;
extern unsigned short IbusOffset;
extern unsigned short VspTemp;
extern unsigned short Vsp_avg;

extern unsigned short Heat_Temperture_avg;
extern unsigned short Temperture_avg;

extern xdata short PllOutTemp;
extern xdata short IqCmdTemp;
extern xdata short IdCmdTemp;

extern xdata short IqPiOut;
extern xdata short IqFb;

extern xdata signed short LatestTheta;
extern xdata unsigned char CloseLoopFlag;
extern xdata unsigned char CCWFlag;
extern xdata unsigned char BemfStateOld;
extern xdata unsigned char BemfState;
extern xdata int Speed;
extern xdata short EstimatedSpeed;
extern xdata long EstimatedSpeed_C;
extern xdata unsigned short RecHallUEdgeCnt;
extern xdata unsigned short HallUEdgeCnt;

extern xdata short BmfVW_Sub;
extern xdata short BmfVW_Sum_Pos_ZeroPoint;
extern xdata short BmfVW_Sum_Neg_ZeroPoint;
extern xdata short BmfU;
extern xdata short BmfV;
extern xdata short BmfW;
extern xdata char ZeroPointCheck;
extern xdata char ZeroPointDebounceCnt;
extern xdata char ZeroPointCnt;
extern xdata char ZeroPointFlag;
extern xdata char ZeroPointFlagOld;

extern bit SlowSpeedFlag;

extern xdata short IaFb;
extern xdata short IbFb;
extern xdata short IcFb;
extern xdata short IdFb;
extern xdata unsigned char LackPhaseState;

//unsigned int RC_Filter(unsigned int DI,DO,DC)
//{
//	DC = DC + DI - DO;
//	return DC>>8;
//}

extern void Motor_Control (void);
extern void ResetMOC (void);

extern void MOC_Init (void);

// Protect
#if (FaultLock_Protect == 1)
extern void FaultLock_Fun (void);
#endif
#if (Vbus_Protect == 1)
extern void Vbus_Protect_Fun (unsigned short Adc_Vbus);
#endif
#if (Temperture_Protect == 1)
extern xdata int Temperture_I;
extern void Temperture_Protect_Fun (unsigned short Adc_Temperture);
#endif
#if (Heat_Temperture_Protect == 1)
extern void Heat_Temperture_Protect_Fun (unsigned short Adc_Temperture);
#endif
extern void AOCP_Protect_Fun (void);
#if (POCP_Protect == 1)
extern void Phase_OCP_Protect_Fun (void);
#endif

// Function
#if (CONTROL_MODE == Power_Limit)
extern int Temp_I;
extern unsigned short Watt;
extern unsigned long Watt_C;
extern void PowerCla_Fun (void);
extern void PowerLimit_Fun (void);
#endif
#if (CONTROL_MODE == Power_Control)
extern unsigned short Watt;
extern unsigned long Watt_C;
extern void PowerCla_Fun (void);
extern void PowerControl_Fun (void);
#endif
#if (VSP_TRI == 1)
extern void Vsp_Fun (void);
#endif
#if (BEMF_TWO_TAILWIND_FUNCTION_RES == 1) || (BEMF_TWO_TAILWIND_FUNCTION_DIODE == 1)
extern void TailWindDetect_TwoBEMF_Fun (void);
#endif
#if (BEMF_ONE_TAILWIND_FUNCTION == 1)
extern void TailWindDetect_OneBEMF_Fun (void);
#endif
#if ((MotorLackPhase == 1) || (MotorLackPhase_Run == 1))
#define Check_Pass 0
#define Check_Fail 1 
#define Check_Busy 2
//extern idata unsigned short Adc_AOCP;
extern xdata signed long IaFb_C,IbFb_C;//,IqFb_C,Id_C;
extern xdata unsigned short LackPhaseCount;
extern xdata unsigned char LackPhaseState;
#endif
#if (PhaseLoss_Fun == 1)
extern void PhaseLoss(void);
#endif
#if (MotorLackPhase == 1)
extern void MotorLackPhase_Fun (void);
#endif
#if (MotorLackPhase_Run == 1)
extern void MotorLackPhase_Run_Fun (void);
#endif

extern void MotorInit_Fun (void);
extern void MotorStart_Flow (void);
extern void MotorStartRetry_Flow (void);
extern void MotorCloseLoop_Fun (void);

extern short Ramp_Fun (short TargetValue,SetpointValue,HighLimit,LowLimit,SetpValue);

extern void TailWindDetect_Fun (void);
extern void TailWindStart_Fun (void);

extern void IPDDetect_Fun (void);
extern void IPDStart_Fun (void);

extern void Break_Fun (void);
#endif